patch-2.4.15 linux/net/irda/irlmp_event.c

Next file: linux/net/irda/irlmp_frame.c
Previous file: linux/net/irda/irlmp.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.14/linux/net/irda/irlmp_event.c linux/net/irda/irlmp_event.c
@@ -11,6 +11,7 @@
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
+ *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -114,6 +115,25 @@
 	irlmp_state_setup_pend
 };
 
+static inline void irlmp_next_lap_state(struct lap_cb *self,
+					IRLMP_STATE state) 
+{
+	/*
+	IRDA_DEBUG(4, __FUNCTION__ "(), LMP LAP = %s\n", irlmp_state[state]);
+	*/
+	self->lap_state = state;
+}
+
+static inline void irlmp_next_lsap_state(struct lsap_cb *self,
+					 LSAP_STATE state) 
+{
+	/*
+	ASSERT(self != NULL, return;);
+	IRDA_DEBUG(4, __FUNCTION__ "(), LMP LSAP = %s\n", irlsap_state[state]);
+	*/
+	self->lsap_state = state;
+}
+
 /* Do connection control events */
 int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event, 
 			struct sk_buff *skb)
@@ -223,7 +243,6 @@
 		IRDA_DEBUG(4, __FUNCTION__ "() LS_CONNECT_REQUEST\n");
 
 		irlmp_next_lap_state(self, LAP_U_CONNECT);
-		self->refcount++;
 
 		/* FIXME: need to set users requested QoS */
 		irlap_connect_request(self->irlap, self->daddr, NULL, 0);
@@ -278,12 +297,12 @@
 		 * the lsaps may already have gone. This avoid getting stuck
 		 * forever in LAP_ACTIVE state - Jean II */
 		if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
+			IRDA_DEBUG(0, __FUNCTION__ "() NO LSAPs !\n");
 			irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
 		}
 		break;
 	case LM_LAP_CONNECT_REQUEST:
 		/* Already trying to connect */
-		self->refcount++;
 		break;
 	case LM_LAP_CONNECT_CONFIRM:
 		/* For all lsap_ce E Associated do LS_Connect_confirm */
@@ -298,12 +317,13 @@
 		 * the lsaps may already have gone. This avoid getting stuck
 		 * forever in LAP_ACTIVE state - Jean II */
 		if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
+			IRDA_DEBUG(0, __FUNCTION__ "() NO LSAPs !\n");
 			irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
 		}
 		break;
 	case LM_LAP_DISCONNECT_INDICATION:
+		IRDA_DEBUG(4, __FUNCTION__ "(), LM_LAP_DISCONNECT_INDICATION\n");
 		irlmp_next_lap_state(self, LAP_STANDBY);
-		self->refcount = 0;
 
 		/* Send disconnect event to all LSAPs using this link */
 		lsap = (struct lsap_cb *) hashbin_get_first( self->lsaps);
@@ -322,9 +342,11 @@
 	case LM_LAP_DISCONNECT_REQUEST:
 		IRDA_DEBUG(4, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n");
 
-		self->refcount--;
-		if (self->refcount == 0)
-			irlmp_next_lap_state(self, LAP_STANDBY);
+		/* One of the LSAP did timeout or was closed, if it was
+		 * the last one, try to get out of here - Jean II */
+		if (HASHBIN_GET_SIZE(self->lsaps) <= 1) {
+			irlap_disconnect_request(self->irlap);
+		}
 		break;
 	default:
 		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
@@ -352,7 +374,6 @@
  	switch (event) {
 	case LM_LAP_CONNECT_REQUEST:
 		IRDA_DEBUG(4, __FUNCTION__ "(), LS_CONNECT_REQUEST\n");
-		self->refcount++;
 
 		/*
 		 *  LAP connection allready active, just bounce back! Since we 
@@ -379,8 +400,6 @@
 		/* Keep state */
 		break;
 	case LM_LAP_DISCONNECT_REQUEST:
-		self->refcount--;
-
 		/*
 		 *  Need to find out if we should close IrLAP or not. If there
 		 *  is only one LSAP connection left on this link, that LSAP 
@@ -419,7 +438,6 @@
 		break;
 	case LM_LAP_DISCONNECT_INDICATION:
 		irlmp_next_lap_state(self, LAP_STANDBY);		
-		self->refcount = 0;
 		
 		/* In some case, at this point our side has already closed
 		 * all lsaps, and we are waiting for the idle_timer to
@@ -517,6 +535,8 @@
 		 * If we receive this event while our LAP is closing down,
 		 * the LM_LAP_CONNECT_REQUEST get lost and we get stuck in
 		 * CONNECT_PEND state forever.
+		 * The other cause of getting stuck down there is if the
+		 * higher layer never reply to the CONNECT_INDICATION.
 		 * Anyway, it make sense to make sure that we always have
 		 * a backup plan. 1 second is plenty (should be immediate).
 		 * Jean II */
@@ -577,9 +597,8 @@
 		 * Jean II */
 		IRDA_DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n");
 
-		/* Here, we should probably disconnect proper */
+		/* Disconnect, get out... - Jean II */
 		self->dlsap_sel = LSAP_ANY;
-		self->conn_skb = NULL;
 		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
 		break;
 	default:
@@ -612,15 +631,6 @@
 	case LM_CONNECT_REQUEST:
 		/* Keep state */
 		break;
-	case LM_CONNECT_INDICATION:
-		/* Will happen in some rare cases when the socket get stuck,
-		 * the other side retries the connect request.
-		 * We just unstuck the socket - Jean II */
-		IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_INDICATION, "
-			   "LSAP stuck in CONNECT_PEND state...\n");
-		/* Keep state */
-		irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
-		break;
 	case LM_CONNECT_RESPONSE:
 		IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_RESPONSE, "
 			   "no indication issued yet\n");
@@ -648,6 +658,8 @@
 
 		/* Go back to disconnected mode, keep the socket waiting */
 		self->dlsap_sel = LSAP_ANY;
+		if(self->conn_skb)
+ 			dev_kfree_skb(self->conn_skb);
 		self->conn_skb = NULL;
 		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
 		break;
@@ -856,7 +868,7 @@
 		irlmp_next_lsap_state(self, LSAP_SETUP);
 		break;
 	case LM_WATCHDOG_TIMEOUT:
-		IRDA_DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "() : WATCHDOG_TIMEOUT !\n");
 
 		ASSERT(self->lap != NULL, return -1;);
 		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
@@ -881,18 +893,4 @@
 		break;	
 	}
 	return ret;
-}
-
-void irlmp_next_lap_state(struct lap_cb *self, IRLMP_STATE state) 
-{
-	IRDA_DEBUG(4, __FUNCTION__ "(), LMP LAP = %s\n", irlmp_state[state]);
-	self->lap_state = state;
-}
-
-void irlmp_next_lsap_state(struct lsap_cb *self, LSAP_STATE state) 
-{
-	ASSERT(self != NULL, return;);
-
-	IRDA_DEBUG(4, __FUNCTION__ "(), LMP LSAP = %s\n", irlsap_state[state]);
-	self->lsap_state = state;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)