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/kernel.h>
28
29#include <net/irda/irda.h>
30#include <net/irda/timer.h>
31#include <net/irda/irlap.h>
32#include <net/irda/irlmp.h>
33#include <net/irda/irlmp_frame.h>
34#include <net/irda/irlmp_event.h>
35
36const char *const irlmp_state[] = {
37	"LAP_STANDBY",
38	"LAP_U_CONNECT",
39	"LAP_ACTIVE",
40};
41
42const char *const irlsap_state[] = {
43	"LSAP_DISCONNECTED",
44	"LSAP_CONNECT",
45	"LSAP_CONNECT_PEND",
46	"LSAP_DATA_TRANSFER_READY",
47	"LSAP_SETUP",
48	"LSAP_SETUP_PEND",
49};
50
51static const char *const irlmp_event[] __maybe_unused = {
52	"LM_CONNECT_REQUEST",
53	"LM_CONNECT_CONFIRM",
54	"LM_CONNECT_RESPONSE",
55	"LM_CONNECT_INDICATION",
56
57	"LM_DISCONNECT_INDICATION",
58	"LM_DISCONNECT_REQUEST",
59
60	"LM_DATA_REQUEST",
61	"LM_UDATA_REQUEST",
62	"LM_DATA_INDICATION",
63	"LM_UDATA_INDICATION",
64
65	"LM_WATCHDOG_TIMEOUT",
66
67	/* IrLAP events */
68	"LM_LAP_CONNECT_REQUEST",
69	"LM_LAP_CONNECT_INDICATION",
70	"LM_LAP_CONNECT_CONFIRM",
71	"LM_LAP_DISCONNECT_INDICATION",
72	"LM_LAP_DISCONNECT_REQUEST",
73	"LM_LAP_DISCOVERY_REQUEST",
74	"LM_LAP_DISCOVERY_CONFIRM",
75	"LM_LAP_IDLE_TIMEOUT",
76};
77
78/* LAP Connection control proto declarations */
79static void irlmp_state_standby  (struct lap_cb *, IRLMP_EVENT,
80				  struct sk_buff *);
81static void irlmp_state_u_connect(struct lap_cb *, IRLMP_EVENT,
82				  struct sk_buff *);
83static void irlmp_state_active   (struct lap_cb *, IRLMP_EVENT,
84				  struct sk_buff *);
85
86/* LSAP Connection control proto declarations */
87static int irlmp_state_disconnected(struct lsap_cb *, IRLMP_EVENT,
88				    struct sk_buff *);
89static int irlmp_state_connect     (struct lsap_cb *, IRLMP_EVENT,
90				    struct sk_buff *);
91static int irlmp_state_connect_pend(struct lsap_cb *, IRLMP_EVENT,
92				    struct sk_buff *);
93static int irlmp_state_dtr         (struct lsap_cb *, IRLMP_EVENT,
94				    struct sk_buff *);
95static int irlmp_state_setup       (struct lsap_cb *, IRLMP_EVENT,
96				    struct sk_buff *);
97static int irlmp_state_setup_pend  (struct lsap_cb *, IRLMP_EVENT,
98				    struct sk_buff *);
99
100static void (*lap_state[]) (struct lap_cb *, IRLMP_EVENT, struct sk_buff *) =
101{
102	irlmp_state_standby,
103	irlmp_state_u_connect,
104	irlmp_state_active,
105};
106
107static int (*lsap_state[])( struct lsap_cb *, IRLMP_EVENT, struct sk_buff *) =
108{
109	irlmp_state_disconnected,
110	irlmp_state_connect,
111	irlmp_state_connect_pend,
112	irlmp_state_dtr,
113	irlmp_state_setup,
114	irlmp_state_setup_pend
115};
116
117static inline void irlmp_next_lap_state(struct lap_cb *self,
118					IRLMP_STATE state)
119{
120	/*
121	  pr_debug("%s(), LMP LAP = %s\n", __func__, irlmp_state[state]);
122	*/
123	self->lap_state = state;
124}
125
126static inline void irlmp_next_lsap_state(struct lsap_cb *self,
127					 LSAP_STATE state)
128{
129	/*
130	IRDA_ASSERT(self != NULL, return;);
131	pr_debug("%s(), LMP LSAP = %s\n", __func__, irlsap_state[state]);
132	*/
133	self->lsap_state = state;
134}
135
136/* Do connection control events */
137int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event,
138			struct sk_buff *skb)
139{
140	IRDA_ASSERT(self != NULL, return -1;);
141	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
142
143	pr_debug("%s(), EVENT = %s, STATE = %s\n",
144		 __func__, irlmp_event[event], irlsap_state[self->lsap_state]);
145
146	return (*lsap_state[self->lsap_state]) (self, event, skb);
147}
148
149/*
150 * Function do_lap_event (event, skb, info)
151 *
152 *    Do IrLAP control events
153 *
154 */
155void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event,
156			struct sk_buff *skb)
157{
158	IRDA_ASSERT(self != NULL, return;);
159	IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
160
161	pr_debug("%s(), EVENT = %s, STATE = %s\n", __func__,
162		 irlmp_event[event],
163		 irlmp_state[self->lap_state]);
164
165	(*lap_state[self->lap_state]) (self, event, skb);
166}
167
168void irlmp_discovery_timer_expired(void *data)
169{
170	/* We always cleanup the log (active & passive discovery) */
171	irlmp_do_expiry();
172
173	irlmp_do_discovery(sysctl_discovery_slots);
174
175	/* Restart timer */
176	irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout * HZ);
177}
178
179void irlmp_watchdog_timer_expired(void *data)
180{
181	struct lsap_cb *self = (struct lsap_cb *) data;
182
183	IRDA_ASSERT(self != NULL, return;);
184	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
185
186	irlmp_do_lsap_event(self, LM_WATCHDOG_TIMEOUT, NULL);
187}
188
189void irlmp_idle_timer_expired(void *data)
190{
191	struct lap_cb *self = (struct lap_cb *) data;
192
193	IRDA_ASSERT(self != NULL, return;);
194	IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
195
196	irlmp_do_lap_event(self, LM_LAP_IDLE_TIMEOUT, NULL);
197}
198
199/*
200 * Send an event on all LSAPs attached to this LAP.
201 */
202static inline void
203irlmp_do_all_lsap_event(hashbin_t *	lsap_hashbin,
204			IRLMP_EVENT	event)
205{
206	struct lsap_cb *lsap;
207	struct lsap_cb *lsap_next;
208
209	/* Note : this function use the new hashbin_find_next()
210	 * function, instead of the old hashbin_get_next().
211	 * This make sure that we are always pointing one lsap
212	 * ahead, so that if the current lsap is removed as the
213	 * result of sending the event, we don't care.
214	 * Also, as we store the context ourselves, if an enumeration
215	 * of the same lsap hashbin happens as the result of sending the
216	 * event, we don't care.
217	 * The only problem is if the next lsap is removed. In that case,
218	 * hashbin_find_next() will return NULL and we will abort the
219	 * enumeration. - Jean II */
220
221	/* Also : we don't accept any skb in input. We can *NOT* pass
222	 * the same skb to multiple clients safely, we would need to
223	 * skb_clone() it. - Jean II */
224
225	lsap = (struct lsap_cb *) hashbin_get_first(lsap_hashbin);
226
227	while (NULL != hashbin_find_next(lsap_hashbin,
228					 (long) lsap,
229					 NULL,
230					 (void *) &lsap_next) ) {
231		irlmp_do_lsap_event(lsap, event, NULL);
232		lsap = lsap_next;
233	}
234}
235
236/*********************************************************************
237 *
238 *    LAP connection control states
239 *
240 ********************************************************************/
241
242/*
243 * Function irlmp_state_standby (event, skb, info)
244 *
245 *    STANDBY, The IrLAP connection does not exist.
246 *
247 */
248static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event,
249				struct sk_buff *skb)
250{
251	IRDA_ASSERT(self->irlap != NULL, return;);
252
253	switch (event) {
254	case LM_LAP_DISCOVERY_REQUEST:
255		/* irlmp_next_station_state( LMP_DISCOVER); */
256
257		irlap_discovery_request(self->irlap, &irlmp->discovery_cmd);
258		break;
259	case LM_LAP_CONNECT_INDICATION:
260		/*  It's important to switch state first, to avoid IrLMP to
261		 *  think that the link is free since IrLMP may then start
262		 *  discovery before the connection is properly set up. DB.
263		 */
264		irlmp_next_lap_state(self, LAP_ACTIVE);
265
266		/* Just accept connection TODO, this should be fixed */
267		irlap_connect_response(self->irlap, skb);
268		break;
269	case LM_LAP_CONNECT_REQUEST:
270		pr_debug("%s() LS_CONNECT_REQUEST\n", __func__);
271
272		irlmp_next_lap_state(self, LAP_U_CONNECT);
273
274		/* FIXME: need to set users requested QoS */
275		irlap_connect_request(self->irlap, self->daddr, NULL, 0);
276		break;
277	case LM_LAP_DISCONNECT_INDICATION:
278		pr_debug("%s(), Error LM_LAP_DISCONNECT_INDICATION\n",
279			 __func__);
280
281		irlmp_next_lap_state(self, LAP_STANDBY);
282		break;
283	default:
284		pr_debug("%s(), Unknown event %s\n",
285			 __func__, irlmp_event[event]);
286		break;
287	}
288}
289
290/*
291 * Function irlmp_state_u_connect (event, skb, info)
292 *
293 *    U_CONNECT, The layer above has tried to open an LSAP connection but
294 *    since the IrLAP connection does not exist, we must first start an
295 *    IrLAP connection. We are now waiting response from IrLAP.
296 * */
297static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event,
298				  struct sk_buff *skb)
299{
300	pr_debug("%s(), event=%s\n", __func__, irlmp_event[event]);
301
302	switch (event) {
303	case LM_LAP_CONNECT_INDICATION:
304		/*  It's important to switch state first, to avoid IrLMP to
305		 *  think that the link is free since IrLMP may then start
306		 *  discovery before the connection is properly set up. DB.
307		 */
308		irlmp_next_lap_state(self, LAP_ACTIVE);
309
310		/* Just accept connection TODO, this should be fixed */
311		irlap_connect_response(self->irlap, skb);
312
313		/* Tell LSAPs that they can start sending data */
314		irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
315
316		/* Note : by the time we get there (LAP retries and co),
317		 * the lsaps may already have gone. This avoid getting stuck
318		 * forever in LAP_ACTIVE state - Jean II */
319		if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
320			pr_debug("%s() NO LSAPs !\n",  __func__);
321			irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
322		}
323		break;
324	case LM_LAP_CONNECT_REQUEST:
325		/* Already trying to connect */
326		break;
327	case LM_LAP_CONNECT_CONFIRM:
328		/* For all lsap_ce E Associated do LS_Connect_confirm */
329		irlmp_next_lap_state(self, LAP_ACTIVE);
330
331		/* Tell LSAPs that they can start sending data */
332		irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
333
334		/* Note : by the time we get there (LAP retries and co),
335		 * the lsaps may already have gone. This avoid getting stuck
336		 * forever in LAP_ACTIVE state - Jean II */
337		if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
338			pr_debug("%s() NO LSAPs !\n",  __func__);
339			irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
340		}
341		break;
342	case LM_LAP_DISCONNECT_INDICATION:
343		pr_debug("%s(), LM_LAP_DISCONNECT_INDICATION\n",  __func__);
344		irlmp_next_lap_state(self, LAP_STANDBY);
345
346		/* Send disconnect event to all LSAPs using this link */
347		irlmp_do_all_lsap_event(self->lsaps,
348					LM_LAP_DISCONNECT_INDICATION);
349		break;
350	case LM_LAP_DISCONNECT_REQUEST:
351		pr_debug("%s(), LM_LAP_DISCONNECT_REQUEST\n",  __func__);
352
353		/* One of the LSAP did timeout or was closed, if it was
354		 * the last one, try to get out of here - Jean II */
355		if (HASHBIN_GET_SIZE(self->lsaps) <= 1) {
356			irlap_disconnect_request(self->irlap);
357		}
358		break;
359	default:
360		pr_debug("%s(), Unknown event %s\n",
361			 __func__, irlmp_event[event]);
362		break;
363	}
364}
365
366/*
367 * Function irlmp_state_active (event, skb, info)
368 *
369 *    ACTIVE, IrLAP connection is active
370 *
371 */
372static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event,
373			       struct sk_buff *skb)
374{
375	switch (event) {
376	case LM_LAP_CONNECT_REQUEST:
377		pr_debug("%s(), LS_CONNECT_REQUEST\n", __func__);
378
379		/*
380		 * IrLAP may have a pending disconnect. We tried to close
381		 * IrLAP, but it was postponed because the link was
382		 * busy or we were still sending packets. As we now
383		 * need it, make sure it stays on. Jean II
384		 */
385		irlap_clear_disconnect(self->irlap);
386
387		/*
388		 *  LAP connection already active, just bounce back! Since we
389		 *  don't know which LSAP that tried to do this, we have to
390		 *  notify all LSAPs using this LAP, but that should be safe to
391		 *  do anyway.
392		 */
393		irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
394
395		/* Needed by connect indication */
396		irlmp_do_all_lsap_event(irlmp->unconnected_lsaps,
397					LM_LAP_CONNECT_CONFIRM);
398		/* Keep state */
399		break;
400	case LM_LAP_DISCONNECT_REQUEST:
401		/*
402		 *  Need to find out if we should close IrLAP or not. If there
403		 *  is only one LSAP connection left on this link, that LSAP
404		 *  must be the one that tries to close IrLAP. It will be
405		 *  removed later and moved to the list of unconnected LSAPs
406		 */
407		if (HASHBIN_GET_SIZE(self->lsaps) > 0) {
408			/* Timer value is checked in irsysctl - Jean II */
409			irlmp_start_idle_timer(self, sysctl_lap_keepalive_time * HZ / 1000);
410		} else {
411			/* No more connections, so close IrLAP */
412
413			/* We don't want to change state just yet, because
414			 * we want to reflect accurately the real state of
415			 * the LAP, not the state we wish it was in,
416			 * so that we don't lose LM_LAP_CONNECT_REQUEST.
417			 * In some cases, IrLAP won't close the LAP
418			 * immediately. For example, it might still be
419			 * retrying packets or waiting for the pf bit.
420			 * As the LAP always send a DISCONNECT_INDICATION
421			 * in PCLOSE or SCLOSE, just change state on that.
422			 * Jean II */
423			irlap_disconnect_request(self->irlap);
424		}
425		break;
426	case LM_LAP_IDLE_TIMEOUT:
427		if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
428			/* Same reasoning as above - keep state */
429			irlap_disconnect_request(self->irlap);
430		}
431		break;
432	case LM_LAP_DISCONNECT_INDICATION:
433		irlmp_next_lap_state(self, LAP_STANDBY);
434
435		/* In some case, at this point our side has already closed
436		 * all lsaps, and we are waiting for the idle_timer to
437		 * expire. If another device reconnect immediately, the
438		 * idle timer will expire in the midle of the connection
439		 * initialisation, screwing up things a lot...
440		 * Therefore, we must stop the timer... */
441		irlmp_stop_idle_timer(self);
442
443		/*
444		 *  Inform all connected LSAP's using this link
445		 */
446		irlmp_do_all_lsap_event(self->lsaps,
447					LM_LAP_DISCONNECT_INDICATION);
448
449		/* Force an expiry of the discovery log.
450		 * Now that the LAP is free, the system may attempt to
451		 * connect to another device. Unfortunately, our entries
452		 * are stale. There is a small window (<3s) before the
453		 * normal discovery will run and where irlmp_connect_request()
454		 * can get the wrong info, so make sure things get
455		 * cleaned *NOW* ;-) - Jean II */
456		irlmp_do_expiry();
457		break;
458	default:
459		pr_debug("%s(), Unknown event %s\n",
460			 __func__, irlmp_event[event]);
461		break;
462	}
463}
464
465/*********************************************************************
466 *
467 *    LSAP connection control states
468 *
469 ********************************************************************/
470
471/*
472 * Function irlmp_state_disconnected (event, skb, info)
473 *
474 *    DISCONNECTED
475 *
476 */
477static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event,
478				    struct sk_buff *skb)
479{
480	int ret = 0;
481
482	IRDA_ASSERT(self != NULL, return -1;);
483	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
484
485	switch (event) {
486#ifdef CONFIG_IRDA_ULTRA
487	case LM_UDATA_INDICATION:
488		/* This is most bizarre. Those packets are  aka unreliable
489		 * connected, aka IrLPT or SOCK_DGRAM/IRDAPROTO_UNITDATA.
490		 * Why do we pass them as Ultra ??? Jean II */
491		irlmp_connless_data_indication(self, skb);
492		break;
493#endif /* CONFIG_IRDA_ULTRA */
494	case LM_CONNECT_REQUEST:
495		pr_debug("%s(), LM_CONNECT_REQUEST\n", __func__);
496
497		if (self->conn_skb) {
498			net_warn_ratelimited("%s: busy with another request!\n",
499					     __func__);
500			return -EBUSY;
501		}
502		/* Don't forget to refcount it (see irlmp_connect_request()) */
503		skb_get(skb);
504		self->conn_skb = skb;
505
506		irlmp_next_lsap_state(self, LSAP_SETUP_PEND);
507
508		/* Start watchdog timer (5 secs for now) */
509		irlmp_start_watchdog_timer(self, 5*HZ);
510
511		irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
512		break;
513	case LM_CONNECT_INDICATION:
514		if (self->conn_skb) {
515			net_warn_ratelimited("%s: busy with another request!\n",
516					     __func__);
517			return -EBUSY;
518		}
519		/* Don't forget to refcount it (see irlap_driver_rcv()) */
520		skb_get(skb);
521		self->conn_skb = skb;
522
523		irlmp_next_lsap_state(self, LSAP_CONNECT_PEND);
524
525		/* Start watchdog timer
526		 * This is not mentionned in the spec, but there is a rare
527		 * race condition that can get the socket stuck.
528		 * If we receive this event while our LAP is closing down,
529		 * the LM_LAP_CONNECT_REQUEST get lost and we get stuck in
530		 * CONNECT_PEND state forever.
531		 * The other cause of getting stuck down there is if the
532		 * higher layer never reply to the CONNECT_INDICATION.
533		 * Anyway, it make sense to make sure that we always have
534		 * a backup plan. 1 second is plenty (should be immediate).
535		 * Jean II */
536		irlmp_start_watchdog_timer(self, 1*HZ);
537
538		irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
539		break;
540	default:
541		pr_debug("%s(), Unknown event %s on LSAP %#02x\n",
542			 __func__, irlmp_event[event], self->slsap_sel);
543		break;
544	}
545	return ret;
546}
547
548/*
549 * Function irlmp_state_connect (self, event, skb)
550 *
551 *    CONNECT
552 *
553 */
554static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event,
555				struct sk_buff *skb)
556{
557	struct lsap_cb *lsap;
558	int ret = 0;
559
560	IRDA_ASSERT(self != NULL, return -1;);
561	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
562
563	switch (event) {
564	case LM_CONNECT_RESPONSE:
565		/*
566		 *  Bind this LSAP to the IrLAP link where the connect was
567		 *  received
568		 */
569		lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self,
570				      NULL);
571
572		IRDA_ASSERT(lsap == self, return -1;);
573		IRDA_ASSERT(self->lap != NULL, return -1;);
574		IRDA_ASSERT(self->lap->lsaps != NULL, return -1;);
575
576		hashbin_insert(self->lap->lsaps, (irda_queue_t *) self,
577			       (long) self, NULL);
578
579		set_bit(0, &self->connected);	/* TRUE */
580
581		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
582				   self->slsap_sel, CONNECT_CNF, skb);
583
584		del_timer(&self->watchdog_timer);
585
586		irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);
587		break;
588	case LM_WATCHDOG_TIMEOUT:
589		/* May happen, who knows...
590		 * Jean II */
591		pr_debug("%s() WATCHDOG_TIMEOUT!\n",  __func__);
592
593		/* Disconnect, get out... - Jean II */
594		self->lap = NULL;
595		self->dlsap_sel = LSAP_ANY;
596		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
597		break;
598	default:
599		/* LM_LAP_DISCONNECT_INDICATION : Should never happen, we
600		 * are *not* yet bound to the IrLAP link. Jean II */
601		pr_debug("%s(), Unknown event %s on LSAP %#02x\n",
602			 __func__, irlmp_event[event], self->slsap_sel);
603		break;
604	}
605	return ret;
606}
607
608/*
609 * Function irlmp_state_connect_pend (event, skb, info)
610 *
611 *    CONNECT_PEND
612 *
613 */
614static int irlmp_state_connect_pend(struct lsap_cb *self, IRLMP_EVENT event,
615				    struct sk_buff *skb)
616{
617	struct sk_buff *tx_skb;
618	int ret = 0;
619
620	IRDA_ASSERT(self != NULL, return -1;);
621	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
622
623	switch (event) {
624	case LM_CONNECT_REQUEST:
625		/* Keep state */
626		break;
627	case LM_CONNECT_RESPONSE:
628		pr_debug("%s(), LM_CONNECT_RESPONSE, no indication issued yet\n",
629			 __func__);
630		/* Keep state */
631		break;
632	case LM_DISCONNECT_REQUEST:
633		pr_debug("%s(), LM_DISCONNECT_REQUEST, not yet bound to IrLAP connection\n",
634			 __func__);
635		/* Keep state */
636		break;
637	case LM_LAP_CONNECT_CONFIRM:
638		pr_debug("%s(), LS_CONNECT_CONFIRM\n",  __func__);
639		irlmp_next_lsap_state(self, LSAP_CONNECT);
640
641		tx_skb = self->conn_skb;
642		self->conn_skb = NULL;
643
644		irlmp_connect_indication(self, tx_skb);
645		/* Drop reference count - see irlmp_connect_indication(). */
646		dev_kfree_skb(tx_skb);
647		break;
648	case LM_WATCHDOG_TIMEOUT:
649		/* Will happen in some rare cases because of a race condition.
650		 * Just make sure we don't stay there forever...
651		 * Jean II */
652		pr_debug("%s() WATCHDOG_TIMEOUT!\n",  __func__);
653
654		/* Go back to disconnected mode, keep the socket waiting */
655		self->lap = NULL;
656		self->dlsap_sel = LSAP_ANY;
657		if(self->conn_skb)
658			dev_kfree_skb(self->conn_skb);
659		self->conn_skb = NULL;
660		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
661		break;
662	default:
663		/* LM_LAP_DISCONNECT_INDICATION : Should never happen, we
664		 * are *not* yet bound to the IrLAP link. Jean II */
665		pr_debug("%s(), Unknown event %s on LSAP %#02x\n",
666			 __func__, irlmp_event[event], self->slsap_sel);
667		break;
668	}
669	return ret;
670}
671
672/*
673 * Function irlmp_state_dtr (self, event, skb)
674 *
675 *    DATA_TRANSFER_READY
676 *
677 */
678static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event,
679			   struct sk_buff *skb)
680{
681	LM_REASON reason;
682	int ret = 0;
683
684	IRDA_ASSERT(self != NULL, return -1;);
685	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
686	IRDA_ASSERT(self->lap != NULL, return -1;);
687
688	switch (event) {
689	case LM_DATA_REQUEST: /* Optimize for the common case */
690		irlmp_send_data_pdu(self->lap, self->dlsap_sel,
691				    self->slsap_sel, FALSE, skb);
692		break;
693	case LM_DATA_INDICATION: /* Optimize for the common case */
694		irlmp_data_indication(self, skb);
695		break;
696	case LM_UDATA_REQUEST:
697		IRDA_ASSERT(skb != NULL, return -1;);
698		irlmp_send_data_pdu(self->lap, self->dlsap_sel,
699				    self->slsap_sel, TRUE, skb);
700		break;
701	case LM_UDATA_INDICATION:
702		irlmp_udata_indication(self, skb);
703		break;
704	case LM_CONNECT_REQUEST:
705		pr_debug("%s(), LM_CONNECT_REQUEST, error, LSAP already connected\n",
706			 __func__);
707		/* Keep state */
708		break;
709	case LM_CONNECT_RESPONSE:
710		pr_debug("%s(), LM_CONNECT_RESPONSE, error, LSAP already connected\n",
711			 __func__);
712		/* Keep state */
713		break;
714	case LM_DISCONNECT_REQUEST:
715		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, self->slsap_sel,
716				   DISCONNECT, skb);
717		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
718		/* Called only from irlmp_disconnect_request(), will
719		 * unbind from LAP over there. Jean II */
720
721		/* Try to close the LAP connection if its still there */
722		if (self->lap) {
723			pr_debug("%s(), trying to close IrLAP\n",
724				 __func__);
725			irlmp_do_lap_event(self->lap,
726					   LM_LAP_DISCONNECT_REQUEST,
727					   NULL);
728		}
729		break;
730	case LM_LAP_DISCONNECT_INDICATION:
731		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
732
733		reason = irlmp_convert_lap_reason(self->lap->reason);
734
735		irlmp_disconnect_indication(self, reason, NULL);
736		break;
737	case LM_DISCONNECT_INDICATION:
738		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
739
740		IRDA_ASSERT(self->lap != NULL, return -1;);
741		IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
742
743		IRDA_ASSERT(skb != NULL, return -1;);
744		IRDA_ASSERT(skb->len > 3, return -1;);
745		reason = skb->data[3];
746
747		 /* Try to close the LAP connection */
748		pr_debug("%s(), trying to close IrLAP\n", __func__);
749		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
750
751		irlmp_disconnect_indication(self, reason, skb);
752		break;
753	default:
754		pr_debug("%s(), Unknown event %s on LSAP %#02x\n",
755			 __func__, irlmp_event[event], self->slsap_sel);
756		break;
757	}
758	return ret;
759}
760
761/*
762 * Function irlmp_state_setup (event, skb, info)
763 *
764 *    SETUP, Station Control has set up the underlying IrLAP connection.
765 *    An LSAP connection request has been transmitted to the peer
766 *    LSAP-Connection Control FSM and we are awaiting reply.
767 */
768static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event,
769			     struct sk_buff *skb)
770{
771	LM_REASON reason;
772	int ret = 0;
773
774	IRDA_ASSERT(self != NULL, return -1;);
775	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
776
777	switch (event) {
778	case LM_CONNECT_CONFIRM:
779		irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);
780
781		del_timer(&self->watchdog_timer);
782
783		irlmp_connect_confirm(self, skb);
784		break;
785	case LM_DISCONNECT_INDICATION:
786		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
787
788		IRDA_ASSERT(self->lap != NULL, return -1;);
789		IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
790
791		IRDA_ASSERT(skb != NULL, return -1;);
792		IRDA_ASSERT(skb->len > 3, return -1;);
793		reason = skb->data[3];
794
795		 /* Try to close the LAP connection */
796		pr_debug("%s(), trying to close IrLAP\n",  __func__);
797		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
798
799		irlmp_disconnect_indication(self, reason, skb);
800		break;
801	case LM_LAP_DISCONNECT_INDICATION:
802		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
803
804		del_timer(&self->watchdog_timer);
805
806		IRDA_ASSERT(self->lap != NULL, return -1;);
807		IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
808
809		reason = irlmp_convert_lap_reason(self->lap->reason);
810
811		irlmp_disconnect_indication(self, reason, skb);
812		break;
813	case LM_WATCHDOG_TIMEOUT:
814		pr_debug("%s() WATCHDOG_TIMEOUT!\n", __func__);
815
816		IRDA_ASSERT(self->lap != NULL, return -1;);
817		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
818		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
819
820		irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);
821		break;
822	default:
823		pr_debug("%s(), Unknown event %s on LSAP %#02x\n",
824			 __func__, irlmp_event[event], self->slsap_sel);
825		break;
826	}
827	return ret;
828}
829
830/*
831 * Function irlmp_state_setup_pend (event, skb, info)
832 *
833 *    SETUP_PEND, An LM_CONNECT_REQUEST has been received from the service
834 *    user to set up an LSAP connection. A request has been sent to the
835 *    LAP FSM to set up the underlying IrLAP connection, and we
836 *    are awaiting confirm.
837 */
838static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event,
839				  struct sk_buff *skb)
840{
841	struct sk_buff *tx_skb;
842	LM_REASON reason;
843	int ret = 0;
844
845	IRDA_ASSERT(self != NULL, return -1;);
846	IRDA_ASSERT(irlmp != NULL, return -1;);
847
848	switch (event) {
849	case LM_LAP_CONNECT_CONFIRM:
850		IRDA_ASSERT(self->conn_skb != NULL, return -1;);
851
852		tx_skb = self->conn_skb;
853		self->conn_skb = NULL;
854
855		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
856				   self->slsap_sel, CONNECT_CMD, tx_skb);
857		/* Drop reference count - see irlap_data_request(). */
858		dev_kfree_skb(tx_skb);
859
860		irlmp_next_lsap_state(self, LSAP_SETUP);
861		break;
862	case LM_WATCHDOG_TIMEOUT:
863		pr_debug("%s() : WATCHDOG_TIMEOUT !\n",  __func__);
864
865		IRDA_ASSERT(self->lap != NULL, return -1;);
866		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
867		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
868
869		irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);
870		break;
871	case LM_LAP_DISCONNECT_INDICATION: /* LS_Disconnect.indication */
872		del_timer( &self->watchdog_timer);
873
874		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
875
876		reason = irlmp_convert_lap_reason(self->lap->reason);
877
878		irlmp_disconnect_indication(self, reason, NULL);
879		break;
880	default:
881		pr_debug("%s(), Unknown event %s on LSAP %#02x\n",
882			 __func__, irlmp_event[event], self->slsap_sel);
883		break;
884	}
885	return ret;
886}
887