diff -u -p linux/include/linux/tty_driver.d0.h linux/include/linux/tty_driver.h
--- linux/include/linux/tty_driver.d0.h	Tue Apr  8 09:56:21 2003
+++ linux/include/linux/tty_driver.h	Tue Apr  8 10:09:09 2003
@@ -157,6 +157,8 @@ struct tty_driver {
 	int  (*chars_in_buffer)(struct tty_struct *tty);
 	int  (*ioctl)(struct tty_struct *tty, struct file * file,
 		    unsigned int cmd, unsigned long arg);
+	int  (*modem_ctrl)(struct tty_struct *tty,
+			   unsigned int set, unsigned int clear);
 	void (*set_termios)(struct tty_struct *tty, struct termios * old);
 	void (*throttle)(struct tty_struct * tty);
 	void (*unthrottle)(struct tty_struct * tty);
diff -u -p linux/drivers/serial/core.d0.c linux/drivers/serial/core.c
--- linux/drivers/serial/core.d0.c	Tue Apr  8 09:51:00 2003
+++ linux/drivers/serial/core.c	Tue Apr  8 10:15:29 2003
@@ -1158,6 +1158,26 @@ uart_ioctl(struct tty_struct *tty, struc
 	return ret;
 }
 
+/*
+ * Called by line disciplines to change the various modem control bits...
+ * Line disciplines are implemented within the kernel, and therefore
+ * we don't want them to use the ioctl function above.
+ * Jean II
+ */
+static int
+uart_modem_ctrl(struct tty_struct *tty, unsigned int set, unsigned int clear)
+{
+	struct uart_state *state = tty->driver_data;
+
+	/* Set new values, if any */
+	/* Locking will be done in there */
+	uart_update_mctrl(state->port, set, clear);
+
+	/* Return new value */
+	return state->port->ops->get_mctrl(state->port);
+}
+
+
 static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios)
 {
 	struct uart_state *state = tty->driver_data;
@@ -2150,6 +2170,7 @@ int uart_register_driver(struct uart_dri
 	normal->chars_in_buffer	= uart_chars_in_buffer;
 	normal->flush_buffer	= uart_flush_buffer;
 	normal->ioctl		= uart_ioctl;
+	normal->modem_ctrl	= uart_modem_ctrl;
 	normal->throttle	= uart_throttle;
 	normal->unthrottle	= uart_unthrottle;
 	normal->send_xchar	= uart_send_xchar;
diff -u -p linux/drivers/net/irda/irtty-sir.d0.c linux/drivers/net/irda/irtty-sir.c
--- linux/drivers/net/irda/irtty-sir.d0.c	Tue Apr  8 09:46:54 2003
+++ linux/drivers/net/irda/irtty-sir.c	Tue Apr  8 10:34:53 2003
@@ -180,32 +180,29 @@ static int irtty_change_speed(struct sir
 static int irtty_set_dtr_rts(struct sir_dev *dev, int dtr, int rts)
 {
 	struct sirtty_cb *priv = dev->priv;
-	int arg = 0;
+	int set = 0;
+	int clear = 0;
 
 	ASSERT(priv != NULL, return -1;);
 	ASSERT(priv->magic == IRTTY_MAGIC, return -1;);
 
-#ifdef TIOCM_OUT2 /* Not defined for ARM */
-	arg = TIOCM_OUT2;
-#endif
 	if (rts)
-		arg |= TIOCM_RTS;
+		set |= TIOCM_RTS;
+	else
+		clear |= TIOCM_RTS;
 	if (dtr)
-		arg |= TIOCM_DTR;
+		set |= TIOCM_DTR;
+	else
+		clear |= TIOCM_DTR;
 
 	/*
-	 * The ioctl() function, or actually set_modem_info() in serial.c
-	 * expects a pointer to the argument in user space. This is working
-	 * here because we are always called from the kIrDAd thread which
-	 * has set_fs(KERNEL_DS) permanently set. Therefore copy_from_user()
-	 * is happy with our arg-parameter being local here in kernel space.
+	 * We can't use ioctl() because it expects a non-null file structure,
+	 * and we don't have that here.
+	 * This function is not yet defined for all tty driver, so
+	 * let's be careful... Jean II
 	 */
-
-	lock_kernel();
-	if (priv->tty->driver.ioctl(priv->tty, NULL, TIOCMSET, (unsigned long) &arg)) { 
-		IRDA_DEBUG(2, "%s(), error doing ioctl!\n", __FUNCTION__);
-	}
-	unlock_kernel();
+	ASSERT(priv->tty->driver.modem_ctrl != NULL, return -1;);
+	priv->tty->driver.modem_ctrl(priv->tty, set, clear);
 
 	return 0;
 }
diff -u -p linux/drivers/net/irda/sir_kthread.d0.c linux/drivers/net/irda/sir_kthread.c
--- linux/drivers/net/irda/sir_kthread.d0.c	Mon Apr  7 18:56:28 2003
+++ linux/drivers/net/irda/sir_kthread.c	Mon Apr  7 18:59:31 2003
@@ -151,6 +151,13 @@ static int irda_thread(void *startup)
 
 	while (irda_rq_queue.thread != NULL) {
 
+		/* We use TASK_INTERRUPTIBLE, rather than
+		 * TASK_UNINTERRUPTIBLE.  Andrew Morton made this
+		 * change ; he told me that it is safe, because "signal
+		 * blocking is now handled in daemonize()", he added
+		 * that the problem is that "uninterruptible sleep
+		 * contributes to load average", making user worry.
+		 * Jean II */
 		set_task_state(current, TASK_INTERRUPTIBLE);
 		add_wait_queue(&irda_rq_queue.kick, &wait);
 		if (list_empty(&irda_rq_queue.request_list))
