diff -u -p linux/net/irda/ircomm/ircomm_tty.d7.c linux/net/irda/ircomm/ircomm_tty.c
--- linux/net/irda/ircomm/ircomm_tty.d7.c	Wed Apr 10 16:44:12 2002
+++ linux/net/irda/ircomm/ircomm_tty.c	Wed Apr 10 16:44:40 2002
@@ -453,8 +453,21 @@ static int ircomm_tty_open(struct tty_st
 	 */
 	if (tty_hung_up_p(filp) ||
 	    (self->flags & ASYNC_CLOSING)) {
-		if (self->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&self->close_wait);
+
+		/* Hm, why are we blocking on ASYNC_CLOSING if we
+		 * do return -EAGAIN/-ERESTARTSYS below anyway?
+		 * IMHO it's either not needed in the first place
+		 * or for some reason we need to make sure the async
+		 * closing has been finished - if so, wouldn't we
+		 * probably better sleep uninterruptible?
+		 */
+
+		if (wait_event_interruptible(self->close_wait, !(self->flags&ASYNC_CLOSING))) {
+			WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
+				__FUNCTION__);
+			return -ERESTARTSYS;
+		}
+
 		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
 #ifdef SERIAL_DO_RESTART
 		return ((self->flags & ASYNC_HUP_NOTIFY) ?
diff -u -p linux/net/irda/af_irda.d7.c linux/net/irda/af_irda.c
--- linux/net/irda/af_irda.d7.c	Wed Apr 10 16:44:21 2002
+++ linux/net/irda/af_irda.c	Fri Apr 12 16:25:19 2002
@@ -568,15 +568,17 @@ static int irda_find_lsap_sel(struct ird
 	if(self->iriap == NULL)
 		return -ENOMEM;
 
-	/* Treat unexpected signals as disconnect */
+	/* Treat unexpected wakeup as disconnect */
 	self->errno = -EHOSTUNREACH;
 
 	/* Query remote LM-IAS */
 	iriap_getvaluebyclass_request(self->iriap, self->saddr, self->daddr,
 				      name, "IrDA:TinyTP:LsapSel");
-	/* Wait for answer (if not already failed) */
-	if(self->iriap != NULL)
-		interruptible_sleep_on(&self->query_wait);
+
+	/* Wait for answer, if not yet finished (or failed) */
+	if (wait_event_interruptible(self->query_wait, (self->iriap==NULL)))
+		/* Treat signals as disconnect */
+		return -EHOSTUNREACH;
 
 	/* Check what happened */
 	if (self->errno)
@@ -877,16 +879,47 @@ static int irda_accept(struct socket *so
 	 *	The read queue this time is holding sockets ready to use
 	 *	hooked into the SABM we saved
 	 */
-	do {
-		if ((skb = skb_dequeue(&sk->receive_queue)) == NULL) {
-			if (flags & O_NONBLOCK)
-				return -EWOULDBLOCK;
 
-			interruptible_sleep_on(sk->sleep);
-			if (signal_pending(current)) 
-				return -ERESTARTSYS;
+	/*
+	 * We can perform the accept only if there is incomming data
+	 * on the listening socket.
+	 * So, we will block the caller until we receive any data.
+	 * If the caller was waiting on select() or poll() before
+	 * calling us, the data is waiting for us ;-)
+	 * Jean II
+	 */
+	skb = skb_dequeue(&sk->receive_queue);
+	if (skb == NULL) {
+		int ret = 0;
+		DECLARE_WAITQUEUE(waitq, current);
+
+		/* Non blocking operation */
+		if (flags & O_NONBLOCK)
+			return -EWOULDBLOCK;
+
+		/* The following code is a cut'n'paste of the
+		 * wait_event_interruptible() macro.
+		 * We don't us the macro because the condition has
+		 * side effects : we want to make sure that only one
+		 * skb get dequeued - Jean II */
+		add_wait_queue(sk->sleep, &waitq);
+		for (;;) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			skb = skb_dequeue(&sk->receive_queue);
+			if (skb != NULL)
+				break;
+			if (!signal_pending(current)) {
+				schedule();
+				continue;
+			}
+			ret = -ERESTARTSYS;
+			break;
 		}
-	} while (skb == NULL);
+		current->state = TASK_RUNNING;
+		remove_wait_queue(sk->sleep, &waitq);
+		if(ret)
+			return -ERESTARTSYS;
+	}
 
  	newsk = newsock->sk;
 	newsk->state = TCP_ESTABLISHED;
@@ -1024,19 +1057,9 @@ static int irda_connect(struct socket *s
 	if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
 		return -EINPROGRESS;
 
-	/* Here, there is a race condition : the state may change between
-	 * our test and the sleep, via irda_connect_confirm().
-	 * The way to workaround that is to sleep with a timeout, so that
-	 * we don't sleep forever and check the state when waking up.
-	 * 50ms is plenty good enough, because the LAP is already connected.
-	 * Jean II */
-	while (sk->state == TCP_SYN_SENT) {
-		interruptible_sleep_on_timeout(sk->sleep, HZ/20);
-		if (signal_pending(current)) {
-			return -ERESTARTSYS;
-		}
-	}
-	
+	if (wait_event_interruptible(*(sk->sleep), (sk->state!=TCP_SYN_SENT)))
+		return -ERESTARTSYS;
+
 	if (sk->state != TCP_ESTABLISHED) {
 		sock->state = SS_UNCONNECTED;
 		return sock_error(sk);	/* Always set at this point */
@@ -1280,17 +1303,14 @@ static int irda_sendmsg(struct socket *s
 	ASSERT(self != NULL, return -1;);
 
 	/* Check if IrTTP is wants us to slow down */
-	while (self->tx_flow == FLOW_STOP) {
-		IRDA_DEBUG(2, __FUNCTION__ "(), IrTTP is busy, going to sleep!\n");
-		interruptible_sleep_on(sk->sleep);
-		
-		/* Check if we are still connected */
-		if (sk->state != TCP_ESTABLISHED)
-			return -ENOTCONN;
-		/* Handle signals */
-		if (signal_pending(current)) 
-			return -ERESTARTSYS;
-	}
+
+	if (wait_event_interruptible(*(sk->sleep),
+	    (self->tx_flow != FLOW_STOP  ||  sk->state != TCP_ESTABLISHED)))
+		return -ERESTARTSYS;
+
+	/* Check if we are still connected */
+	if (sk->state != TCP_ESTABLISHED)
+		return -ENOTCONN;
 
 	/* Check that we don't send out to big frames */
 	if (len > self->max_data_size) {
@@ -1382,14 +1402,23 @@ static int irda_recvmsg_dgram(struct soc
  *
  *    Sleep until data has arrive. But check for races..
  *
+ *    The caller is expected to deal with the situation when we return
+ *    due to pending signals. And even if not, the peeked skb might have
+ *    been already dequeued due to concurrent operation.
+ *    Currently irda_recvmsg_stream() is the only caller and is ok.
+ * Return 0 if condition packet has arrived, -ERESTARTSYS if signal_pending()
+ * Only used once in irda_recvmsg_stream() -> inline
  */
-static void irda_data_wait(struct sock *sk)
+static inline int irda_data_wait(struct sock *sk)
 {
+	int ret = 0;
 	if (!skb_peek(&sk->receive_queue)) {
 		set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
-		interruptible_sleep_on(sk->sleep);
+		__wait_event_interruptible(*(sk->sleep),
+			(skb_peek(&sk->receive_queue)!=NULL), ret);
 		clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
 	}
+	return(ret);
 }
 
 /*
@@ -1444,8 +1473,8 @@ static int irda_recvmsg_stream(struct so
 
 			if (noblock)
 				return -EAGAIN;
-			irda_data_wait(sk);
-			if (signal_pending(current))
+			/* Wait process until data arrives */
+			if (irda_data_wait(sk))
 				return -ERESTARTSYS;
 			continue;
 		}
@@ -2281,7 +2310,12 @@ bed:
 		self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
 					 irda_getvalue_confirm);
 
-		/* Treat unexpected signals as disconnect */
+		if (self->iriap == NULL) {
+			kfree(ias_opt);
+			return -ENOMEM;
+		}
+
+		/* Treat unexpected wakeup as disconnect */
 		self->errno = -EHOSTUNREACH;
 
 		/* Query remote LM-IAS */
@@ -2289,9 +2323,17 @@ bed:
 					      self->saddr, daddr,
 					      ias_opt->irda_class_name,
 					      ias_opt->irda_attrib_name);
-		/* Wait for answer (if not already failed) */
-		if(self->iriap != NULL)
-			interruptible_sleep_on(&self->query_wait);
+
+		/* Wait for answer, if not yet finished (or failed) */
+		if (wait_event_interruptible(self->query_wait,
+					     (self->iriap == NULL))) {
+			/* pending request uses copy of ias_opt-content
+			 * we can free it regardless! */
+			kfree(ias_opt);
+			/* Treat signals as disconnect */
+			return -EHOSTUNREACH;
+		}
+
 		/* Check what happened */
 		if (self->errno)
 		{
@@ -2348,12 +2390,14 @@ bed:
 		irlmp_update_client(self->ckey, self->mask,
 				    irda_selective_discovery_indication,
 				    NULL, (void *) self);
-		
+
 		/* Do some discovery (and also return cached results) */
 		irlmp_discovery_request(self->nslots);
-		
+
 		/* Wait until a node is discovered */
 		if (!self->cachediscovery) {
+			int ret = 0;
+
 			IRDA_DEBUG(1, __FUNCTION__ 
 				   "(), nothing discovered yet, going to sleep...\n");
 
@@ -2362,9 +2406,12 @@ bed:
 			self->watchdog.data = (unsigned long) self;
 			self->watchdog.expires = jiffies + (val * HZ/1000);
 			add_timer(&(self->watchdog));
+			self->errno = 0;
 
 			/* Wait for IR-LMP to call us back */
-			interruptible_sleep_on(&self->query_wait);
+			__wait_event_interruptible(self->query_wait,
+			   (self->cachediscovery!=NULL || self->errno==-ETIME),
+						   ret);
 
 			/* If watchdog is still activated, kill it! */
 			if(timer_pending(&(self->watchdog)))
@@ -2372,6 +2419,9 @@ bed:
 
 			IRDA_DEBUG(1, __FUNCTION__ 
 				   "(), ...waking up !\n");
+
+			if (ret != 0)
+				return ret;
 		}
 		else
 			IRDA_DEBUG(1, __FUNCTION__ 
