diff -u -p linux/include/net/irda/irlmp.d2.h linux/include/net/irda/irlmp.h
--- linux/include/net/irda/irlmp.d2.h	Fri Nov  2 14:11:19 2001
+++ linux/include/net/irda/irlmp.h	Fri Nov  2 18:37:29 2001
@@ -131,7 +131,6 @@ struct lap_cb {
 
 	struct irlap_cb *irlap;   /* Instance of IrLAP layer */
 	hashbin_t *lsaps;         /* LSAP associated with this link */
-	int refcount;
 
 	__u8  caddr;  /* Connection address */
  	__u32 saddr;  /* Source device address */
diff -u -p linux/include/net/irda/irlmp_event.d2.h linux/include/net/irda/irlmp_event.h
--- linux/include/net/irda/irlmp_event.d2.h	Fri Nov  2 18:47:47 2001
+++ linux/include/net/irda/irlmp_event.h	Fri Nov  2 15:46:29 2001
@@ -103,10 +103,6 @@ void irlmp_watchdog_timer_expired(void *
 void irlmp_discovery_timer_expired(void *data);
 void irlmp_idle_timer_expired(void *data);
 
-void irlmp_next_station_state(IRLMP_STATE state);
-void irlmp_next_lsap_state(struct lsap_cb *self, LSAP_STATE state);
-void irlmp_next_lap_state(struct lap_cb *self, IRLMP_STATE state);
-
 void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event, 
 			struct sk_buff *skb);
 int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event, 
diff -u -p linux/include/net/irda/irlap_event.d2.h linux/include/net/irda/irlap_event.h
--- linux/include/net/irda/irlap_event.d2.h	Fri Nov  2 18:47:12 2001
+++ linux/include/net/irda/irlap_event.h	Fri Nov  2 18:11:20 2001
@@ -103,6 +103,7 @@ typedef enum {
 	DISCOVERY_TIMER_EXPIRED,
 	WD_TIMER_EXPIRED,
 	BACKOFF_TIMER_EXPIRED,
+	MEDIA_BUSY_TIMER_EXPIRED,
 } IRLAP_EVENT;
 
 /*
diff -u -p linux/net/irda/irlmp.d2.c linux/net/irda/irlmp.c
--- linux/net/irda/irlmp.d2.c	Wed Oct 31 15:44:59 2001
+++ linux/net/irda/irlmp.c	Fri Nov  2 16:53:17 2001
@@ -75,7 +75,7 @@ int irlmp_proc_read(char *buf, char **st
  */
 int __init irlmp_init(void)
 {
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, __FUNCTION__ "()\n");
 	/* Initialize the irlmp structure. */
 	irlmp = kmalloc( sizeof(struct irlmp_cb), GFP_KERNEL);
 	if (irlmp == NULL)
@@ -170,14 +170,14 @@ struct lsap_cb *irlmp_open_lsap(__u8 sls
 #endif /* CONFIG_IRDA_ULTRA */
 	} else
 		self->dlsap_sel = LSAP_ANY;
-	self->connected = FALSE;
+	/* self->connected = FALSE; -> already NULL via memset() */
 
 	init_timer(&self->watchdog_timer);
 
 	ASSERT(notify->instance != NULL, return NULL;);
 	self->notify = *notify;
 
-	irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
+	self->lsap_state = LSAP_DISCONNECTED;
 	
 	/* Insert into queue of unconnected LSAPs */
 	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self, (int) self, 
@@ -237,6 +237,7 @@ void irlmp_close_lsap(struct lsap_cb *se
 		ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
 		lsap = hashbin_remove(lap->lsaps, (int) self, NULL);
 	}
+	self->lap = NULL;
 	/* Check if we found the LSAP! If not then try the unconnected lsaps */
 	if (!lsap) {
 		lsap = hashbin_remove(irlmp->unconnected_lsaps, (int) self, 
@@ -281,7 +282,7 @@ void irlmp_register_link(struct irlap_cb
 	lap->daddr = DEV_ADDR_ANY;
 	lap->lsaps = hashbin_new(HB_GLOBAL);
 
-	irlmp_next_lap_state(lap, LAP_STANDBY);
+	lap->lap_state = LAP_STANDBY;
 	
 	init_timer(&lap->idle_timer);
 
@@ -346,7 +347,7 @@ int irlmp_connect_request(struct lsap_cb
 	      "(), slsap_sel=%02x, dlsap_sel=%02x, saddr=%08x, daddr=%08x\n", 
 	      self->slsap_sel, dlsap_sel, saddr, daddr);
 	
-	if (self->connected) 
+	if (test_bit(0, &self->connected))
 		return -EISCONN;
 	
 	/* Client must supply destination device address */
@@ -435,7 +436,7 @@ int irlmp_connect_request(struct lsap_cb
 
 	hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (int) self, NULL);
 
-	self->connected = TRUE;
+	set_bit(0, &self->connected);	/* TRUE */
 	
 	/*
 	 *  User supplied qos specifications?
@@ -481,6 +482,8 @@ void irlmp_connect_indication(struct lsa
 		self->notify.connect_indication(self->notify.instance, self, 
 						&self->qos, max_seg_size, 
 						max_header_size, skb);
+	else
+		dev_kfree_skb(skb);
 }
 
 /*
@@ -495,7 +498,7 @@ int irlmp_connect_response(struct lsap_c
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
 	ASSERT(userdata != NULL, return -1;);
 
-	self->connected = TRUE;
+	set_bit(0, &self->connected);	/* TRUE */
 
 	IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", 
 		   self->slsap_sel, self->dlsap_sel);
@@ -543,7 +546,8 @@ void irlmp_connect_confirm(struct lsap_c
 		self->notify.connect_confirm(self->notify.instance, self,
 					     &self->qos, max_seg_size,
 					     max_header_size, skb);
-	}
+	} else
+		dev_kfree_skb(skb);
 }
 
 /*
@@ -598,16 +602,18 @@ int irlmp_disconnect_request(struct lsap
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
+	ASSERT(userdata != NULL, return -1;);
 
-	/* Already disconnected? */
-	if (!self->connected) {
-		WARNING(__FUNCTION__ "(), already disconnected!\n");
+	/* Already disconnected ?
+	 * There is a race condition between irlmp_disconnect_indication()
+	 * and us that might mess up the hashbins below. This fixes it.
+	 * Jean II */
+	if (! test_and_clear_bit(0, &self->connected)) {
+		IRDA_DEBUG(0, __FUNCTION__ "(), already disconnected!\n");
+		dev_kfree_skb(userdata);
 		return -1;
 	}
 
-	ASSERT(userdata != NULL, return -1;);
-	ASSERT(self->connected == TRUE, return -1;);
-	
 	skb_push(userdata, LMP_CONTROL_HEADER);
 
 	/* 
@@ -634,7 +640,6 @@ int irlmp_disconnect_request(struct lsap
 		       NULL);
 	
 	/* Reset some values */
-	self->connected = FALSE;
 	self->dlsap_sel = LSAP_ANY;
 	self->lap = NULL;
 	
@@ -651,16 +656,23 @@ void irlmp_disconnect_indication(struct 
 {
 	struct lsap_cb *lsap;
 
-	IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lmp_reasons[reason]);	
+	IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lmp_reasons[reason]);
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
- 	ASSERT(self->connected == TRUE, return;); 
 
 	IRDA_DEBUG(3, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", 
 		   self->slsap_sel, self->dlsap_sel);
 
-	self->connected = FALSE;
-	self->dlsap_sel = LSAP_ANY;
+	/* Already disconnected ?
+	 * There is a race condition between irlmp_disconnect_request()
+	 * and us that might mess up the hashbins below. This fixes it.
+	 * Jean II */
+	if (! test_and_clear_bit(0, &self->connected)) {
+		IRDA_DEBUG(0, __FUNCTION__ "(), already disconnected!\n");
+		if (userdata)
+			dev_kfree_skb(userdata);
+		return;
+	}
 
 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
 	irlmp->cache.valid = FALSE;
@@ -679,6 +691,7 @@ void irlmp_disconnect_indication(struct 
 	hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) lsap, (int) lsap, 
 		       NULL);
 
+	self->dlsap_sel = LSAP_ANY;
 	self->lap = NULL;
 	
 	/*
@@ -689,7 +702,8 @@ void irlmp_disconnect_indication(struct 
 						   self, reason, userdata);
 	else {
 		IRDA_DEBUG(0, __FUNCTION__ "(), no handler\n");
-		dev_kfree_skb(userdata);
+		if (userdata)
+			dev_kfree_skb(userdata);
 	}
 }
 
@@ -1401,7 +1415,7 @@ __u32 irlmp_register_client(__u16 hint_m
 	irlmp_client_t *client;
 	__u32 handle;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, __FUNCTION__ "()\n");
 	ASSERT(irlmp != NULL, return 0;);
 	
 	/* Get a unique handle for this client */
@@ -1673,14 +1687,15 @@ int irlmp_proc_read(char *buf, char **st
 
 		len += sprintf(buf+len, "saddr: %#08x, daddr: %#08x, ",
 			       lap->saddr, lap->daddr); 
-		len += sprintf(buf+len, "refcount: %d", lap->refcount);
+		len += sprintf(buf+len, "num lsaps: %d",
+			       HASHBIN_GET_SIZE(lap->lsaps));
 		len += sprintf(buf+len, "\n");
 
-		len += sprintf(buf+len, "\nConnected LSAPs:\n");
+		len += sprintf(buf+len, "\n  Connected LSAPs:\n");
 		self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
 		while (self != NULL) {
 			ASSERT(self->magic == LMP_LSAP_MAGIC, return 0;);
-			len += sprintf(buf+len, "lsap state: %s, ", 
+			len += sprintf(buf+len, "  lsap state: %s, ", 
 				       irlsap_state[ self->lsap_state]);
 			len += sprintf(buf+len, 
 				       "slsap_sel: %#02x, dlsap_sel: %#02x, ",
diff -u -p linux/net/irda/irlmp_event.d2.c linux/net/irda/irlmp_event.c
--- linux/net/irda/irlmp_event.d2.c	Fri Nov  2 13:55:19 2001
+++ linux/net/irda/irlmp_event.c	Fri Nov  2 19:06:59 2001
@@ -114,6 +114,25 @@ static int (*lsap_state[])( struct lsap_
 	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 +242,6 @@ static void irlmp_state_standby(struct l
 		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 +296,12 @@ static void irlmp_state_u_connect(struct
 		 * 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 +316,13 @@ static void irlmp_state_u_connect(struct
 		 * 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(1, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\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);
@@ -320,11 +339,13 @@ static void irlmp_state_u_connect(struct
 		}
 		break;
 	case LM_LAP_DISCONNECT_REQUEST:
-		IRDA_DEBUG(4, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n");
+		IRDA_DEBUG(1, __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 +373,6 @@ static void irlmp_state_active(struct la
  	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 +399,6 @@ static void irlmp_state_active(struct la
 		/* 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 +437,6 @@ static void irlmp_state_active(struct la
 		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 +534,8 @@ static int irlmp_state_disconnected(stru
 		 * 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 +596,8 @@ static int irlmp_state_connect(struct ls
 		 * 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 +630,6 @@ static int irlmp_state_connect_pend(stru
 	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 +657,8 @@ static int irlmp_state_connect_pend(stru
 
 		/* 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 +867,7 @@ static int irlmp_state_setup_pend(struct
 		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 +892,4 @@ static int irlmp_state_setup_pend(struct
 		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;
 }
diff -u -p linux/net/irda/timer.d2.c linux/net/irda/timer.c
--- linux/net/irda/timer.d2.c	Fri Nov  2 18:04:22 2001
+++ linux/net/irda/timer.c	Fri Nov  2 19:03:02 2001
@@ -106,17 +106,13 @@ void irlap_stop_mbusy_timer(struct irlap
 	if(timer_pending(&self->media_busy_timer))
 		del_timer(&self->media_busy_timer);
 
-#ifdef CONFIG_IRDA_ULTRA
-	/* Send any pending Ultra frames if any */
-	if (!skb_queue_empty(&self->txq_ultra))
-		/* Note : we don't send the frame, just post an event.
-		 * Frames will be sent only if we are in NDM mode (see
-		 * irlap_event.c).
-		 * Also, moved this code from irlap_media_busy_expired()
-		 * to here to catch properly all cases...
-		 * Jean II */
-		irlap_do_event(self, SEND_UI_FRAME, NULL, NULL);
-#endif /* CONFIG_IRDA_ULTRA */
+	/* If we are in NDM, there is a bunch of events in LAP that
+	 * that be pending due to the media_busy condition, such as
+	 * CONNECT_REQUEST and SEND_UI_FRAME. If we don't generate
+	 * an event, they will wait forever...
+	 * Jean II */
+	if (self->state == LAP_NDM)
+		irlap_do_event(self, MEDIA_BUSY_TIMER_EXPIRED, NULL, NULL);
 }
 
 void irlmp_start_watchdog_timer(struct lsap_cb *self, int timeout) 
@@ -237,5 +233,6 @@ void irlap_media_busy_expired(void* data
 	ASSERT(self != NULL, return;);
 
 	irda_device_set_media_busy(self->netdev, FALSE);
-	/* Note : will deal with Ultra frames */
+	/* Note : the LAP event will be send in irlap_stop_mbusy_timer(),
+	* to catch other cases and do it after clearing the mbusy flag */
 }
diff -u -p linux/net/irda/irlap_event.d2.c linux/net/irda/irlap_event.c
--- linux/net/irda/irlap_event.d2.c	Fri Nov  2 16:28:13 2001
+++ linux/net/irda/irlap_event.c	Fri Nov  2 19:15:59 2001
@@ -114,6 +114,7 @@ static const char *irlap_event[] = {
 	"DISCOVERY_TIMER_EXPIRED",
 	"WD_TIMER_EXPIRED",
 	"BACKOFF_TIMER_EXPIRED",
+	"MEDIA_BUSY_TIMER_EXPIRED",
 };
 
 const char *irlap_state[] = {
@@ -264,6 +265,15 @@ void irlap_do_event(struct irlap_cb *sel
 		}
 		break;
 	case LAP_NDM:
+		/* This one *should* not pend in this state, except if a
+		 * socket try to connect and immediately disconnected.
+		 * clear - Jean II */
+		if (self->disconnect_pending) {
+			IRDA_DEBUG(0, __FUNCTION__ "(), Clear pending disconnect!\n");
+			self->disconnect_pending = FALSE;
+			self->connect_pending = FALSE;
+			irlap_disconnect_indication(self, LAP_DISC_INDICATION);
+		}
 		/* Check if we should try to connect */
 		if ((self->connect_pending) && !self->media_busy) {
 			self->connect_pending = FALSE;
@@ -440,6 +450,20 @@ static int irlap_state_ndm(struct irlap_
 			irlap_discovery_indication(self, info->discovery); 
 		}
 		break;
+	case MEDIA_BUSY_TIMER_EXPIRED:
+		/* A bunch of events may be postponed because the media is busy
+		 * This event indicate the the media is free, therefore
+		 * we can process those events... - Jean II */
+#ifdef CONFIG_IRDA_ULTRA
+		/* Send any pending Ultra frames if any */
+		if (!skb_queue_empty(&self->txq_ultra))
+			/* We don't send the frame, just post an event.
+			 * Also, previously this code was in timer.c...
+			 * Jean II */
+			ret = (*state[self->state])(self, SEND_UI_FRAME, 
+						    NULL, NULL);
+#endif /* CONFIG_IRDA_ULTRA */
+	  break;
 #ifdef CONFIG_IRDA_ULTRA
 	case SEND_UI_FRAME:
 		/* Only allowed to repeat an operation twice */
@@ -735,8 +759,10 @@ static int irlap_state_conn(struct irlap
 
 		break;		
 	case DISCONNECT_REQUEST:
+		IRDA_DEBUG(0, __FUNCTION__ "(), Disconnect request!\n");
 		irlap_send_dm_frame(self);
-		irlap_next_state( self, LAP_CONN);
+		irlap_next_state( self, LAP_NDM);
+		irlap_disconnect_indication(self, LAP_DISC_INDICATION);
 		break;
 	default:
 		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event,
@@ -1417,13 +1443,12 @@ static int irlap_state_nrm_p(struct irla
 		irlap_start_final_timer(self, self->final_timeout);
 		break;
 	case RECV_RD_RSP:
-		IRDA_DEBUG(0, __FUNCTION__ "(), RECV_RD_RSP\n");
+		IRDA_DEBUG(1, __FUNCTION__ "(), RECV_RD_RSP\n");
 
-		irlap_next_state(self, LAP_PCLOSE);
-		irlap_send_disc_frame(self);
 		irlap_flush_all_queues(self);
-		irlap_start_final_timer(self, self->final_timeout);
-		self->retry_count = 0;
+		irlap_next_state(self, LAP_XMIT_P);
+		/* Call back the LAP state machine to do a proper disconnect */
+		irlap_disconnect_request(self);
 		break;
 	default:
 		IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", 
