diff -u -p linux/include/net/irda/irport.d0.h linux/include/net/irda/irport.h
--- linux/include/net/irda/irport.d0.h	Mon May 12 18:12:18 2003
+++ linux/include/net/irda/irport.h	Mon May 12 18:17:06 2003
@@ -67,6 +67,7 @@ struct irport_cb {
 	__u32 new_speed;
 	int mode;
 	int index;                 /* Instance index */
+	int transmitting;	   /* Are we transmitting ? */
 
 	spinlock_t lock;           /* For serializing operations */
 
diff -u -p linux/drivers/net/irda/irport.d0.c linux/drivers/net/irda/irport.c
--- linux/drivers/net/irda/irport.d0.c	Mon May 12 18:03:50 2003
+++ linux/drivers/net/irda/irport.c	Tue May 13 13:07:43 2003
@@ -11,6 +11,7 @@
  * Sources:	  serial.c by Linus Torvalds 
  * 
  *     Copyright (c) 1997, 1998, 1999-2000 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 2000-2003 Jean Tourrilhes, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -48,6 +49,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/delay.h>
 #include <linux/rtnetlink.h>
 
 #include <asm/system.h>
@@ -72,14 +74,14 @@ static unsigned int qos_mtt_bits = 0x03;
 static struct irport_cb *dev_self[] = { NULL, NULL, NULL, NULL};
 static char *driver_name = "irport";
 
-static void irport_write_wakeup(struct irport_cb *self);
-static int  irport_write(int iobase, int fifo_size, __u8 *buf, int len);
-static void irport_receive(struct irport_cb *self);
+static inline void irport_write_wakeup(struct irport_cb *self);
+static inline int  irport_write(int iobase, int fifo_size, __u8 *buf, int len);
+static inline void irport_receive(struct irport_cb *self);
 
 static int  irport_net_init(struct net_device *dev);
 static int  irport_net_ioctl(struct net_device *dev, struct ifreq *rq, 
 			     int cmd);
-static int  irport_is_receiving(struct irport_cb *self);
+static inline int  irport_is_receiving(struct irport_cb *self);
 static int  irport_set_dtr_rts(struct net_device *dev, int dtr, int rts);
 static int  irport_raw_write(struct net_device *dev, __u8 *buf, int len);
 static struct net_device_stats *irport_net_get_stats(struct net_device *dev);
@@ -169,7 +171,7 @@ irport_open(int i, unsigned int iobase, 
 	self->io.sir_base  = iobase;
         self->io.sir_ext   = IO_EXTENT;
         self->io.irq       = irq;
-        self->io.fifo_size = 16;
+        self->io.fifo_size = 16;		/* 16550A and compatible */
 
 	/* Initialize QoS for this device */
 	irda_init_max_qos_capabilies(&self->qos);
@@ -181,39 +183,47 @@ irport_open(int i, unsigned int iobase, 
 	irda_qos_bits_to_value(&self->qos);
 	
 	self->flags = IFF_SIR|IFF_PIO;
+	self->mode = IRDA_IRLAP;
+
+	/* Bootstrap ZeroCopy Rx */
+	self->rx_buff.truesize = IRDA_SKB_MAX_MTU;
+	self->rx_buff.skb = __dev_alloc_skb(self->rx_buff.truesize,
+					    GFP_KERNEL);
+	if (self->rx_buff.skb == NULL)
+		return NULL;
+	skb_reserve(self->rx_buff.skb, 1);
+	self->rx_buff.head = self->rx_buff.skb->data;
+	/* No need to memset the buffer, unless you are really pedantic */
+
+	/* Finish setup the Rx buffer descriptor */
+	self->rx_buff.in_frame = FALSE;
+	self->rx_buff.state = OUTSIDE_FRAME;
+	self->rx_buff.data = self->rx_buff.head;
 
 	/* Specify how much memory we want */
-	self->rx_buff.truesize = 4000; 
 	self->tx_buff.truesize = 4000;
 	
 	/* Allocate memory if needed */
-	if (self->rx_buff.truesize > 0) {
-		self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
-						      GFP_KERNEL);
-		if (self->rx_buff.head == NULL)
-			return NULL;
-		memset(self->rx_buff.head, 0, self->rx_buff.truesize);
-	}
 	if (self->tx_buff.truesize > 0) {
 		self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
 						      GFP_KERNEL);
 		if (self->tx_buff.head == NULL) {
-			kfree(self->rx_buff.head);
+			kfree_skb(self->rx_buff.skb);
+			self->rx_buff.skb = NULL;
+			self->rx_buff.head = NULL;
 			return NULL;
 		}
 		memset(self->tx_buff.head, 0, self->tx_buff.truesize);
 	}	
-	self->rx_buff.in_frame = FALSE;
-	self->rx_buff.state = OUTSIDE_FRAME;
 	self->tx_buff.data = self->tx_buff.head;
-	self->rx_buff.data = self->rx_buff.head;
-	self->mode = IRDA_IRLAP;
 
 	if (!(dev = dev_alloc("irda%d", &err))) {
 		ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
 		return NULL;
 	}
 	self->netdev = dev;
+	/* Keep track of module usage */
+	SET_MODULE_OWNER(dev);
 
 	/* May be overridden by piggyback drivers */
  	dev->priv = (void *) self;
@@ -241,7 +251,8 @@ irport_open(int i, unsigned int iobase, 
 		ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
 		return NULL;
 	}
-	MESSAGE("IrDA: Registered device %s\n", dev->name);
+	MESSAGE("IrDA: Registered device %s (irport io=0x%X irq=%d)\n",
+		dev->name, iobase, irq);
 
 	return self;
 }
@@ -270,8 +281,9 @@ int irport_close(struct irport_cb *self)
 	if (self->tx_buff.head)
 		kfree(self->tx_buff.head);
 	
-	if (self->rx_buff.head)
-		kfree(self->rx_buff.head);
+	if (self->rx_buff.skb)
+		kfree_skb(self->rx_buff.skb);
+	self->rx_buff.skb = NULL;
 	
 	/* Remove ourselves */
 	dev_self[self->index] = NULL;
@@ -306,6 +318,9 @@ void irport_stop(struct irport_cb *self)
 
 	/* We can't lock, we may be called from a FIR driver - Jean II */
 
+	/* We are not transmitting any more */
+	self->transmitting = 0;
+
 	/* Reset UART */
 	outb(0, iobase+UART_MCR);
 	
@@ -327,6 +342,33 @@ int irport_probe(int iobase)
 }
 
 /*
+ * Function irport_get_fcr (speed)
+ *
+ *    Compute value of fcr
+ *
+ */
+static inline unsigned int irport_get_fcr(__u32 speed)
+{
+	unsigned int fcr;    /* FIFO control reg */
+
+	/* Enable fifos */
+	fcr = UART_FCR_ENABLE_FIFO;
+
+	/* 
+	 * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
+	 * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
+	 * about this timeout since it will always be fast enough. 
+	 */
+	if (speed < 38400)
+		fcr |= UART_FCR_TRIGGER_1;
+	else 
+		//fcr |= UART_FCR_TRIGGER_14;
+		fcr |= UART_FCR_TRIGGER_8;
+
+	return(fcr);
+}
+ 
+/*
  * Function irport_change_speed (self, speed)
  *
  *    Set speed of IrDA port to specified baudrate
@@ -337,11 +379,12 @@ void irport_change_speed(void *priv, __u
 {
 	struct irport_cb *self = (struct irport_cb *) priv;
 	int iobase; 
-	int fcr;    /* FIFO control reg */
-	int lcr;    /* Line control reg */
+	unsigned int fcr;    /* FIFO control reg */
+	unsigned int lcr;    /* Line control reg */
 	int divisor;
 
 	ASSERT(self != NULL, return;);
+	ASSERT(speed != 0, return;);
 
 	IRDA_DEBUG(1, "%s(), Setting speed to: %d - iobase=%#x\n",
 		    __FUNCTION__, speed, self->io.sir_base);
@@ -358,18 +401,9 @@ void irport_change_speed(void *priv, __u
 
 	divisor = SPEED_MAX/speed;
 	
-	fcr = UART_FCR_ENABLE_FIFO;
+	/* Get proper fifo configuration */
+	fcr = irport_get_fcr(speed);
 
-	/* 
-	 * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
-	 * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
-	 * about this timeout since it will always be fast enough. 
-	 */
-	if (self->io.speed < 38400)
-		fcr |= UART_FCR_TRIGGER_1;
-	else 
-		fcr |= UART_FCR_TRIGGER_14;
-        
 	/* IrDA ports use 8N1 */
 	lcr = UART_LCR_WLEN8;
 	
@@ -380,7 +414,7 @@ void irport_change_speed(void *priv, __u
 	outb(fcr,		  iobase+UART_FCR); /* Enable FIFO's */
 
 	/* Turn on interrups */
-	/* This will generate a fata interrupt storm.
+	/* This will generate a fatal interrupt storm.
 	 * People calling us will do that properly - Jean II */
 	//outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER);
 }
@@ -467,8 +501,8 @@ int __irport_change_speed(struct irda_ta
 		irda_task_next_state(task, IRDA_TASK_DONE);
 		ret = -1;
 		break;
-	}	
-	/* Put stuff in the sate we found them - Jean II */
+	}
+	/* Put stuff in the state we found them - Jean II */
 	if(wasunlocked) {
 		spin_unlock_irqrestore(&self->lock, flags);
 	}
@@ -477,98 +511,6 @@ int __irport_change_speed(struct irda_ta
 }
 
 /*
- * Function irport_write_wakeup (tty)
- *
- *    Called by the driver when there's room for more data.  If we have
- *    more packets to send, we send them here.
- *
- */
-static void irport_write_wakeup(struct irport_cb *self)
-{
-	int actual = 0;
-	int iobase;
-	int fcr;
-
-	ASSERT(self != NULL, return;);
-
-	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
-
-	iobase = self->io.sir_base;
-
-	/* Finished with frame?  */
-	if (self->tx_buff.len > 0)  {
-		/* Write data left in transmit buffer */
-		actual = irport_write(iobase, self->io.fifo_size, 
-				      self->tx_buff.data, self->tx_buff.len);
-		self->tx_buff.data += actual;
-		self->tx_buff.len  -= actual;
-
-		/* Turn on transmit finished interrupt. */
-		outb(UART_IER_THRI, iobase+UART_IER); 
-	} else {
-		/* 
-		 *  Now serial buffer is almost free & we can start 
-		 *  transmission of another packet. But first we must check
-		 *  if we need to change the speed of the hardware
-		 */
-		if (self->new_speed) {
-			IRDA_DEBUG(5, "%s(), Changing speed!\n", __FUNCTION__);
-			irda_task_execute(self, __irport_change_speed, 
-					  irport_change_speed_complete, 
-					  NULL, (void *) self->new_speed);
-			self->new_speed = 0;
-			IRDA_DEBUG(5, "%s(), Speed changed!\n", __FUNCTION__ );
-		} else {
-			/* Tell network layer that we want more frames */
-			netif_wake_queue(self->netdev);
-		}
-		self->stats.tx_packets++;
-
-		/* 
-		 * Reset Rx FIFO to make sure that all reflected transmit data
-		 * is discarded. This is needed for half duplex operation
-		 */
-		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR;
-		if (self->io.speed < 38400)
-			fcr |= UART_FCR_TRIGGER_1;
-		else 
-			fcr |= UART_FCR_TRIGGER_14;
-
-		outb(fcr, iobase+UART_FCR);
-
-		/* Turn on receive interrupts */
-		outb(UART_IER_RDI, iobase+UART_IER);
-	}
-}
-
-/*
- * Function irport_write (driver)
- *
- *    Fill Tx FIFO with transmit data
- *
- */
-static int irport_write(int iobase, int fifo_size, __u8 *buf, int len)
-{
-	int actual = 0;
-
-	/* Tx FIFO should be empty! */
-	if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
-		IRDA_DEBUG(0, "%s(), failed, fifo not empty!\n", __FUNCTION__);
-		return 0;
-	}
-        
-	/* Fill FIFO with current frame */
-	while ((fifo_size-- > 0) && (actual < len)) {
-		/* Transmit next byte */
-		outb(buf[actual], iobase+UART_TX);
-
-		actual++;
-	}
-        
-	return actual;
-}
-
-/*
  * Function irport_change_speed_complete (task)
  *
  *    Called when the change speed operation completes
@@ -604,24 +546,80 @@ static void irport_timeout(struct net_de
 {
 	struct irport_cb *self;
 	int iobase;
+	int iir, lsr;
 	unsigned long flags;
 
 	self = (struct irport_cb *) dev->priv;
+	ASSERT(self != NULL, return;);
 	iobase = self->io.sir_base;
 	
-	WARNING("%s: transmit timed out\n", dev->name);
+	WARNING("%s: transmit timed out, jiffies = %ld, trans_start = %ld\n",
+		dev->name, jiffies, dev->trans_start);
 	spin_lock_irqsave(&self->lock, flags);
+
+	/* Debug what's happening... */
+
+	/* Get interrupt status */
+	lsr = inb(iobase+UART_LSR);
+	/* Read interrupt register */
+	iir = inb(iobase+UART_IIR);
+	IRDA_DEBUG(0, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", 
+		   __FUNCTION__, iir, lsr, iobase);
+
+	IRDA_DEBUG(0, "%s(), transmitting=%d, remain=%d, done=%d\n", 
+		   __FUNCTION__, self->transmitting, self->tx_buff.len,
+		   self->tx_buff.data - self->tx_buff.head);
+
+	/* Now, restart the port */
 	irport_start(self);
 	self->change_speed(self->priv, self->io.speed);
 	/* This will re-enable irqs */
 	outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER);
+	dev->trans_start = jiffies;
 	spin_unlock_irqrestore(&self->lock, flags);
 
-	dev->trans_start = jiffies;
 	netif_wake_queue(dev);
 }
  
 /*
+ * Function irport_wait_hw_transmitter_finish ()
+ *
+ *    Wait for the real end of HW transmission
+ *
+ * The UART is a strict FIFO, and we get called only when we have finished
+ * pushing data to the FIFO, so the maximum amount of time we must wait
+ * is only for the FIFO to drain out.
+ *
+ * We use a simple calibrated loop. We may need to adjust the loop
+ * delay (udelay) to balance I/O traffic and latency. And we also need to
+ * adjust the maximum timeout.
+ * It would probably be better to wait for the proper interrupt,
+ * but it doesn't seem to be available.
+ *
+ * We can't use jiffies or kernel timers because :
+ * 1) We are called from the interrupt handler, which disable softirqs,
+ * so jiffies won't be increased
+ * 2) Jiffies granularity is usually very coarse (10ms), and we don't
+ * want to wait that long to detect stuck hardware.
+ * Jean II
+ */
+
+static void irport_wait_hw_transmitter_finish(struct irport_cb *self)
+{
+	int iobase;
+	int count = 1000;	/* 1 ms */
+	
+	iobase = self->io.sir_base;
+
+	/* Calibrated busy loop */
+	while((count-- > 0) && !(inb(iobase+UART_LSR) & UART_LSR_TEMT))
+		udelay(1);
+
+	if(count == 0)
+		IRDA_DEBUG(0, "%s(): stuck transmitter\n", __FUNCTION__);
+}
+
+/*
  * Function irport_hard_start_xmit (struct sk_buff *skb, struct net_device *dev)
  *
  *    Transmits the current frame until FIFO is full, then
@@ -645,8 +643,8 @@ int irport_hard_xmit(struct sk_buff *skb
 	iobase = self->io.sir_base;
 
 	netif_stop_queue(dev);
-	
-	/* Make sure tests *& speed change are atomic */
+
+	/* Make sure tests & speed change are atomic */
 	spin_lock_irqsave(&self->lock, flags);
 
 	/* Check if we need to change the speed */
@@ -654,10 +652,21 @@ int irport_hard_xmit(struct sk_buff *skb
 	if ((speed != self->io.speed) && (speed != -1)) {
 		/* Check for empty frame */
 		if (!skb->len) {
+			/*
+			 * We send frames one by one in SIR mode (no
+			 * pipelining), so at this point, if we were sending
+			 * a previous frame, we just received the interrupt
+			 * telling us it is finished (UART_IIR_THRI).
+			 * Therefore, waiting for the transmitter to really
+			 * finish draining the fifo won't take too long.
+			 * And the interrupt handler is not expected to run.
+			 * - Jean II */
+			irport_wait_hw_transmitter_finish(self);
 			/* Better go there already locked - Jean II */
 			irda_task_execute(self, __irport_change_speed, 
 					  irport_change_speed_complete, 
 					  NULL, (void *) speed);
+			dev->trans_start = jiffies;
 			spin_unlock_irqrestore(&self->lock, flags);
 			dev_kfree_skb(skb);
 			return 0;
@@ -674,9 +683,13 @@ int irport_hard_xmit(struct sk_buff *skb
 	
 	self->stats.tx_bytes += self->tx_buff.len;
 
+	/* We are transmitting */
+	self->transmitting = 1;
+
 	/* Turn on transmit finished interrupt. Will fire immediately!  */
 	outb(UART_IER_THRI, iobase+UART_IER); 
 
+	dev->trans_start = jiffies;
 	spin_unlock_irqrestore(&self->lock, flags);
 
 	dev_kfree_skb(skb);
@@ -685,12 +698,100 @@ int irport_hard_xmit(struct sk_buff *skb
 }
         
 /*
+ * Function irport_write (driver)
+ *
+ *    Fill Tx FIFO with transmit data
+ *
+ * Called only from irport_write_wakeup()
+ */
+static inline int irport_write(int iobase, int fifo_size, __u8 *buf, int len)
+{
+	int actual = 0;
+
+	/* Fill FIFO with current frame */
+	while ((actual < fifo_size) && (actual < len)) {
+		/* Transmit next byte */
+		outb(buf[actual], iobase+UART_TX);
+
+		actual++;
+	}
+        
+	return actual;
+}
+
+/*
+ * Function irport_write_wakeup (tty)
+ *
+ *    Called by the driver when there's room for more data.  If we have
+ *    more packets to send, we send them here.
+ *
+ * Called only from irport_interrupt()
+ * Make sure this function is *not* called while we are receiving,
+ * otherwise we will reset fifo and loose data :-(
+ */
+static inline void irport_write_wakeup(struct irport_cb *self)
+{
+	int actual = 0;
+	int iobase;
+	unsigned int fcr;
+
+	ASSERT(self != NULL, return;);
+
+	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+
+	iobase = self->io.sir_base;
+
+	/* Finished with frame?  */
+	if (self->tx_buff.len > 0)  {
+		/* Write data left in transmit buffer */
+		actual = irport_write(iobase, self->io.fifo_size, 
+				      self->tx_buff.data, self->tx_buff.len);
+		self->tx_buff.data += actual;
+		self->tx_buff.len  -= actual;
+	} else {
+		/* 
+		 *  Now serial buffer is almost free & we can start 
+		 *  transmission of another packet. But first we must check
+		 *  if we need to change the speed of the hardware
+		 */
+		if (self->new_speed) {
+			irport_wait_hw_transmitter_finish(self);
+			irda_task_execute(self, __irport_change_speed, 
+					  irport_change_speed_complete, 
+					  NULL, (void *) self->new_speed);
+			self->new_speed = 0;
+		} else {
+			/* Tell network layer that we want more frames */
+			netif_wake_queue(self->netdev);
+		}
+		self->stats.tx_packets++;
+
+		/* 
+		 * Reset Rx FIFO to make sure that all reflected transmit data
+		 * is discarded. This is needed for half duplex operation
+		 */
+		fcr = irport_get_fcr(self->io.speed);
+		fcr |= UART_FCR_CLEAR_RCVR;
+		outb(fcr, iobase+UART_FCR);
+
+		/* Finished transmitting */
+		self->transmitting = 0;
+
+		/* Turn on receive interrupts */
+		outb(UART_IER_RDI, iobase+UART_IER);
+
+		IRDA_DEBUG(1, "%s() : finished Tx\n", __FUNCTION__);
+	}
+}
+
+/*
  * Function irport_receive (self)
  *
  *    Receive one frame from the infrared port
  *
+ * Called only from irport_interrupt()
  */
-static void irport_receive(struct irport_cb *self) 
+static inline void irport_receive(struct irport_cb *self) 
 {
 	int boguscount = 0;
 	int iobase;
@@ -739,40 +840,51 @@ irqreturn_t irport_interrupt(int irq, vo
 
 	iobase = self->io.sir_base;
 
-	iir = inb(iobase+UART_IIR) & UART_IIR_ID;
-	while (iir) {
-		handled = 1;
+	/* Cut'n'paste interrupt routine from serial.c
+	 * This version try to minimise latency and I/O operations.
+	 * Simplified and modified to enforce half duplex operation.
+	 * - Jean II */
 
-		/* Clear interrupt */
+	/* Check status even is iir reg is cleared, more robust and
+	 * eliminate a read on the I/O bus - Jean II */
+	do {
+		/* Get interrupt status ; Clear interrupt */
 		lsr = inb(iobase+UART_LSR);
-
-		IRDA_DEBUG(4, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", 
-			   __FUNCTION__, iir, lsr, iobase);
-
-		switch (iir) {
-		case UART_IIR_RLSI:
-			IRDA_DEBUG(2, "%s(), RLSI\n", __FUNCTION__);
-			break;
-		case UART_IIR_RDI:
-			/* Receive interrupt */
-			irport_receive(self);
-			break;
-		case UART_IIR_THRI:
-			if (lsr & UART_LSR_THRE)
-				/* Transmitter ready for data */
-				irport_write_wakeup(self);
-			break;
-		default:
-			IRDA_DEBUG(0, "%s(), unhandled IIR=%#x\n", __FUNCTION__, iir);
-			break;
-		} 
 		
-		/* Make sure we don't stay here too long */
-		if (boguscount++ > 100)
+		/* Are we receiving or transmitting ? */
+		if(!self->transmitting) {
+			/* Received something ? */
+			if (lsr & UART_LSR_DR)
+				irport_receive(self);
+		} else {
+			/* Room in Tx fifo ? */
+			if (lsr & (UART_LSR_THRE | UART_LSR_TEMT))
+				irport_write_wakeup(self);
+		}
+
+		/* A bit hackish, but working as expected... Jean II */
+		if(lsr & (UART_LSR_THRE | UART_LSR_TEMT | UART_LSR_DR))
+			handled = 1;
+
+		/* Make sure we don't stay here to long */
+		if (boguscount++ > 10) {
+			WARNING("%s() irq handler looping : lsr=%02x\n",
+				__FUNCTION__, lsr);
 			break;
+		}
+
+		/* Read interrupt register */
+ 	        iir = inb(iobase+UART_IIR);
+
+		/* Enable this debug only when no other options and at low
+		 * bit rates, otherwise it may cause Rx overruns (lsr=63).
+		 * - Jean II */
+		IRDA_DEBUG(6, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", 
+			    __FUNCTION__, iir, lsr, iobase);
+
+		/* As long as interrupt pending... */
+	} while ((iir & UART_IIR_NO_INT) == 0);
 
- 	        iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-	}
 	spin_unlock(&self->lock);
 	return IRQ_RETVAL(handled);
 }
@@ -800,8 +912,8 @@ int irport_net_open(struct net_device *d
 	char hwname[16];
 	unsigned long flags;
 
-	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
-	
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+
 	ASSERT(dev != NULL, return -1;);
 	self = (struct irport_cb *) dev->priv;
 
@@ -815,7 +927,12 @@ int irport_net_open(struct net_device *d
 	}
 
 	spin_lock_irqsave(&self->lock, flags);
+	/* Init uart */
 	irport_start(self);
+	/* Set 9600 bauds per default, including at the dongle */
+	irda_task_execute(self, __irport_change_speed, 
+			  irport_change_speed_complete, 
+			  NULL, (void *) 9600);
 	spin_unlock_irqrestore(&self->lock, flags);
 
 
@@ -828,12 +945,9 @@ int irport_net_open(struct net_device *d
 	 */
 	self->irlap = irlap_open(dev, &self->qos, hwname);
 
-	/* FIXME: change speed of dongle */
 	/* Ready to play! */
 
 	netif_start_queue(dev);
-	
-	MOD_INC_USE_COUNT;
 
 	return 0;
 }
@@ -873,40 +987,16 @@ int irport_net_close(struct net_device *
 
 	free_irq(self->io.irq, dev);
 
-	MOD_DEC_USE_COUNT;
-
 	return 0;
 }
 
 /*
- * Function irport_wait_until_sent (self)
- *
- *    Delay exectution until finished transmitting
- *
- */
-#if 0
-void irport_wait_until_sent(struct irport_cb *self)
-{
-	int iobase;
-
-	iobase = self->io.sir_base;
-
-	/* Wait until Tx FIFO is empty */
-	while (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
-		IRDA_DEBUG(2, "%s(), waiting!\n", __FUNCTION__);
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(MSECS_TO_JIFFIES(60));
-	}
-}
-#endif
-
-/*
  * Function irport_is_receiving (self)
  *
  *    Returns true is we are currently receiving data
  *
  */
-static int irport_is_receiving(struct irport_cb *self)
+static inline int irport_is_receiving(struct irport_cb *self)
 {
 	return (self->rx_buff.state != OUTSIDE_FRAME);
 }
@@ -997,6 +1087,12 @@ static int irport_net_ioctl(struct net_d
 			ret = -EPERM;
 			break;
 		}
+
+		/* Locking :
+		 * irda_device_dongle_init() can't be locked.
+		 * irda_task_execute() doesn't need to be locked.
+		 * Jean II
+		 */
 
 		/* Initialize dongle */
 		dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/