/*********************************************************************
 * 
 * Filename:	  irport.c
 * Version:	  1.0
 * Description:   Half duplex serial port SIR driver for IrDA. 
 * Status:	  Experimental.
 * Author:	  Dag Brattli <dagb@cs.uit.no>
 * Created at:	  Sun Aug  3 13:49:59 1997
 * Modified at:   Fri Jan 28 20:22:38 2000
 * Modified by:   Dag Brattli <dagb@cs.uit.no>
 * 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 
 *     published by the Free Software Foundation; either version 2 of 
 *     the License, or (at your option) any later version.
 * 
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *     GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License 
 *     along with this program; if not, write to the Free Software 
 *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
 *     MA 02111-1307 USA
 *
 *     This driver is ment to be a small half duplex serial driver to be
 *     used for IR-chipsets that has a UART (16550) compatibility mode. 
 *     Eventually it will replace irtty, because of irtty has some 
 *     problems that is hard to get around when we don't have control
 *     over the serial driver. This driver may also be used by FIR 
 *     drivers to handle SIR mode for them.
 *
 ********************************************************************/

#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/serial_reg.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/rtnetlink.h>
#include <linux/bitops.h>

#include <asm/system.h>
#include <asm/io.h>

#include <net/irda/irda.h>
#include <net/irda/wrapper.h>
#include "irport.h"

#define IO_EXTENT 8

/* 
 * Currently you'll need to set these values using insmod like this:
 * insmod irport io=0x3e8 irq=11
 */
static unsigned int io[]  = { ~0, ~0, ~0, ~0 };
static unsigned int irq[] = { 0, 0, 0, 0 };

static unsigned int qos_mtt_bits = 0x03;

static struct irport_cb *dev_self[] = { NULL, NULL, NULL, NULL};
static char *driver_name = "irport";

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_ioctl(struct net_device *dev, struct ifreq *rq, 
			     int cmd);
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);
static int irport_change_speed_complete(struct irda_task *task);
static void irport_timeout(struct net_device *dev);

static irqreturn_t irport_interrupt(int irq, void *dev_id,
				    struct pt_regs *regs);
static int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev);
static void irport_change_speed(void *priv, __u32 speed);
static int irport_net_open(struct net_device *dev);
static int irport_net_close(struct net_device *dev);

static struct irport_cb *
irport_open(int i, unsigned int iobase, unsigned int irq)
{
	struct net_device *dev;
	struct irport_cb *self;

	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);

	/* Lock the port that we need */
	if (!request_region(iobase, IO_EXTENT, driver_name)) {
		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
			   __FUNCTION__, iobase);
		goto err_out1;
	}

	/*
	 *  Allocate new instance of the driver
	 */
	dev = alloc_irdadev(sizeof(struct irport_cb));
	if (!dev) {
		IRDA_ERROR("%s(), can't allocate memory for "
			   "irda device!\n", __FUNCTION__);
		goto err_out2;
	}

	self = dev->priv;
	spin_lock_init(&self->lock);

	/* Need to store self somewhere */
	dev_self[i] = self;
	self->priv = self;
	self->index = i;

	/* Initialize IO */
	self->io.sir_base  = iobase;
        self->io.sir_ext   = IO_EXTENT;
        self->io.irq       = irq;
        self->io.fifo_size = 16;		/* 16550A and compatible */

	/* Initialize QoS for this device */
	irda_init_max_qos_capabilies(&self->qos);
	
	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
		IR_115200;

	self->qos.min_turn_time.bits = qos_mtt_bits;
	irda_qos_bits_to_value(&self->qos);
	
	/* 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) {
		IRDA_ERROR("%s(), can't allocate memory for "
			   "receive buffer!\n", __FUNCTION__);
		goto err_out3;
	}
	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->tx_buff.truesize = 4000;
	
	/* Allocate memory if needed */
	if (self->tx_buff.truesize > 0) {
		self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
						      GFP_KERNEL);
		if (self->tx_buff.head == NULL) {
			IRDA_ERROR("%s(), can't allocate memory for "
				   "transmit buffer!\n", __FUNCTION__);
			goto err_out4;
		}
		memset(self->tx_buff.head, 0, self->tx_buff.truesize);
	}	
	self->tx_buff.data = self->tx_buff.head;

	self->netdev = dev;
	/* Keep track of module usage */
	SET_MODULE_OWNER(dev);

	/* May be overridden by piggyback drivers */
	self->interrupt    = irport_interrupt;
	self->change_speed = irport_change_speed;

	/* Override the network functions we need to use */
	dev->hard_start_xmit = irport_hard_xmit;
	dev->tx_timeout	     = irport_timeout;
	dev->watchdog_timeo  = HZ;  /* Allow time enough for speed change */
	dev->open            = irport_net_open;
	dev->stop            = irport_net_close;
	dev->get_stats	     = irport_net_get_stats;
	dev->do_ioctl        = irport_net_ioctl;

	/* Make ifconfig display some details */
	dev->base_addr = iobase;
	dev->irq = irq;

	if (register_netdev(dev)) {
		IRDA_ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
		goto err_out5;
	}
	IRDA_MESSAGE("IrDA: Registered device %s (irport io=0x%X irq=%d)\n",
		dev->name, iobase, irq);

	return self;
 err_out5:
	kfree(self->tx_buff.head);
 err_out4:
	kfree_skb(self->rx_buff.skb);
 err_out3:
	free_netdev(dev);
	dev_self[i] = NULL;
 err_out2:
	release_region(iobase, IO_EXTENT);
 err_out1:
	return NULL;
}

static int irport_close(struct irport_cb *self)
{
	IRDA_ASSERT(self != NULL, return -1;);

	/* We are not using any dongle anymore! */
	if (self->dongle)
		irda_device_dongle_cleanup(self->dongle);
	self->dongle = NULL;
	
	/* Remove netdevice */
	unregister_netdev(self->netdev);

	/* Release the IO-port that this driver is using */
	IRDA_DEBUG(0 , "%s(), Releasing Region %03x\n", 
		   __FUNCTION__, self->io.sir_base);
	release_region(self->io.sir_base, self->io.sir_ext);

	if (self->tx_buff.head)
		kfree(self->tx_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;
	free_netdev(self->netdev);
	
	return 0;
}

static void irport_stop(struct irport_cb *self)
{
	int iobase;

	iobase = self->io.sir_base;

	/* 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);
	
	/* Turn off interrupts */
	outb(0, iobase+UART_IER);
}

static void irport_start(struct irport_cb *self)
{
	int iobase;

	iobase = self->io.sir_base;

	irport_stop(self);
	
	/* We can't lock, we may be called from a FIR driver - Jean II */

	/* Initialize UART */
	outb(UART_LCR_WLEN8, iobase+UART_LCR);  /* Reset DLAB */
	outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR);
	
	/* Turn on interrups */
	outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER);
}

/*
 * Function irport_probe (void)
 *
 *    Start IO port 
 *
 */
int irport_probe(int iobase)
{
	IRDA_DEBUG(4, "%s(), iobase=%#x\n", __FUNCTION__, iobase);

	return 0;
}

/*
 * 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
 *
 * This function should be called with irq off and spin-lock.
 */
static void irport_change_speed(void *priv, __u32 speed)
{
	struct irport_cb *self = (struct irport_cb *) priv;
	int iobase; 
	unsigned int fcr;    /* FIFO control reg */
	unsigned int lcr;    /* Line control reg */
	int divisor;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(speed != 0, return;);

	IRDA_DEBUG(1, "%s(), Setting speed to: %d - iobase=%#x\n",
		    __FUNCTION__, speed, self->io.sir_base);

	/* We can't lock, we may be called from a FIR driver - Jean II */

	iobase = self->io.sir_base;
	
	/* Update accounting for new speed */
	self->io.speed = speed;

	/* Turn off interrupts */
	outb(0, iobase+UART_IER); 

	divisor = SPEED_MAX/speed;
	
	/* Get proper fifo configuration */
	fcr = irport_get_fcr(speed);

	/* IrDA ports use 8N1 */
	lcr = UART_LCR_WLEN8;
	
	outb(UART_LCR_DLAB | lcr, iobase+UART_LCR); /* Set DLAB */
	outb(divisor & 0xff,      iobase+UART_DLL); /* Set speed */
	outb(divisor >> 8,	  iobase+UART_DLM);
	outb(lcr,		  iobase+UART_LCR); /* Set 8N1	*/
	outb(fcr,		  iobase+UART_FCR); /* Enable FIFO's */

	/* Turn on interrups */
	/* 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);
}

/*
 * Function __irport_change_speed (instance, state, param)
 *
 *    State machine for changing speed of the device. We do it this way since
 *    we cannot use schedule_timeout() when we are in interrupt context
 *
 */
int __irport_change_speed(struct irda_task *task)
{
	struct irport_cb *self;
	__u32 speed = (__u32) task->param;
	unsigned long flags = 0;
	int wasunlocked = 0;
	int ret = 0;

	IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies); 

	self = (struct irport_cb *) task->instance;

	IRDA_ASSERT(self != NULL, return -1;);

	/* Locking notes : this function may be called from irq context with
	 * spinlock, via irport_write_wakeup(), or from non-interrupt without
	 * spinlock (from the task timer). Yuck !
	 * This is ugly, and unsafe is the spinlock is not already aquired.
	 * This will be fixed when irda-task get rewritten.
	 * Jean II */
	if (!spin_is_locked(&self->lock)) {
		spin_lock_irqsave(&self->lock, flags);
		wasunlocked = 1;
	}

	switch (task->state) {
	case IRDA_TASK_INIT:
	case IRDA_TASK_WAIT:
		/* Are we ready to change speed yet? */
		if (self->tx_buff.len > 0) {
			task->state = IRDA_TASK_WAIT;

			/* Try again later */
			ret = msecs_to_jiffies(20);
			break;
		}

		if (self->dongle)
			irda_task_next_state(task, IRDA_TASK_CHILD_INIT);
		else
			irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
		break;
	case IRDA_TASK_CHILD_INIT:
		/* Go to default speed */
		self->change_speed(self->priv, 9600);

		/* Change speed of dongle */
		if (irda_task_execute(self->dongle,
				      self->dongle->issue->change_speed, 
				      NULL, task, (void *) speed))
		{
			/* Dongle need more time to change its speed */
			irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);

			/* Give dongle 1 sec to finish */
			ret = msecs_to_jiffies(1000);
		} else
			/* Child finished immediately */
			irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
		break;
	case IRDA_TASK_CHILD_WAIT:
		IRDA_WARNING("%s(), changing speed of dongle timed out!\n", __FUNCTION__);
		ret = -1;		
		break;
	case IRDA_TASK_CHILD_DONE:
		/* Finally we are ready to change the speed */
		self->change_speed(self->priv, speed);
		
		irda_task_next_state(task, IRDA_TASK_DONE);
		break;
	default:
		IRDA_ERROR("%s(), unknown state %d\n",
			   __FUNCTION__, task->state);
		irda_task_next_state(task, IRDA_TASK_DONE);
		ret = -1;
		break;
	}
	/* Put stuff in the state we found them - Jean II */
	if(wasunlocked) {
		spin_unlock_irqrestore(&self->lock, flags);
	}

	return ret;
}

/*
 * Function irport_change_speed_complete (task)
 *
 *    Called when the change speed operation completes
 *
 */
static int irport_change_speed_complete(struct irda_task *task)
{
	struct irport_cb *self;

	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);

	self = (struct irport_cb *) task->instance;

	IRDA_ASSERT(self != NULL, return -1;);
	IRDA_ASSERT(self->netdev != NULL, return -1;);

	/* Finished changing speed, so we are not busy any longer */
	/* Signal network layer so it can try to send the frame */

	netif_wake_queue(self->netdev);
	
	return 0;
}

/*
 * Function irport_timeout (struct net_device *dev)
 *
 *    The networking layer thinks we timed out.
 *
 */

static void irport_timeout(struct net_device *dev)
{
	struct irport_cb *self;
	int iobase;
	int iir, lsr;
	unsigned long flags;

	self = (struct irport_cb *) dev->priv;
	IRDA_ASSERT(self != NULL, return;);
	iobase = self->io.sir_base;
	
	IRDA_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);

	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
 *    waits until the next transmitt interrupt, and continues until the
 *    frame is transmitted.
 */
static int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct irport_cb *self;
	unsigned long flags;
	int iobase;
	s32 speed;

	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);

	IRDA_ASSERT(dev != NULL, return 0;);
	
	self = (struct irport_cb *) dev->priv;
	IRDA_ASSERT(self != NULL, return 0;);

	iobase = self->io.sir_base;

	netif_stop_queue(dev);

	/* Make sure tests & speed change are atomic */
	spin_lock_irqsave(&self->lock, flags);

	/* Check if we need to change the speed */
	speed = irda_get_next_speed(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;
		} else
			self->new_speed = speed;
	}

	/* Init tx buffer */
	self->tx_buff.data = self->tx_buff.head;

        /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
	self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
					   self->tx_buff.truesize);
	
	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);
	
	return 0;
}
        
/*
 * 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;

	IRDA_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 inline void irport_receive(struct irport_cb *self) 
{
	int boguscount = 0;
	int iobase;

	IRDA_ASSERT(self != NULL, return;);

	iobase = self->io.sir_base;

	/*  
	 * Receive all characters in Rx FIFO, unwrap and unstuff them. 
         * async_unwrap_char will deliver all found frames  
	 */
	do {
		async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, 
				  inb(iobase+UART_RX));

		/* Make sure we don't stay here too long */
		if (boguscount++ > 32) {
			IRDA_DEBUG(2,"%s(), breaking!\n", __FUNCTION__);
			break;
		}
	} while (inb(iobase+UART_LSR) & UART_LSR_DR);	
}

/*
 * Function irport_interrupt (irq, dev_id, regs)
 *
 *    Interrupt handler
 */
static irqreturn_t irport_interrupt(int irq, void *dev_id,
				    struct pt_regs *regs) 
{
	struct net_device *dev = (struct net_device *) dev_id;
	struct irport_cb *self;
	int boguscount = 0;
	int iobase;
	int iir, lsr;
	int handled = 0;

	if (!dev) {
		IRDA_WARNING("%s() irq %d for unknown device.\n", __FUNCTION__, irq);
		return IRQ_NONE;
	}
	self = (struct irport_cb *) dev->priv;

	spin_lock(&self->lock);

	iobase = self->io.sir_base;

	/* 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 */

	/* 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);
		
		/* 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) {
			IRDA_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);

	spin_unlock(&self->lock);
	return IRQ_RETVAL(handled);
}

/*
 * Function irport_net_open (dev)
 *
 *    Network device is taken up. Usually this is done by "ifconfig irda0 up" 
 *   
 */
static int irport_net_open(struct net_device *dev)
{
	struct irport_cb *self;
	int iobase;
	char hwname[16];
	unsigned long flags;

	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);

	IRDA_ASSERT(dev != NULL, return -1;);
	self = (struct irport_cb *) dev->priv;

	iobase = self->io.sir_base;

	if (request_irq(self->io.irq, self->interrupt, 0, dev->name, 
			(void *) dev)) {
		IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n",
			   __FUNCTION__, self->io.irq);
		return -EAGAIN;
	}

	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);


	/* Give self a hardware name */
	sprintf(hwname, "SIR @ 0x%03x", self->io.sir_base);

	/* 
	 * Open new IrLAP layer instance, now that everything should be
	 * initialized properly 
	 */
	self->irlap = irlap_open(dev, &self->qos, hwname);

	/* Ready to play! */

	netif_start_queue(dev);

	return 0;
}

/*
 * Function irport_net_close (self)
 *
 *    Network device is taken down. Usually this is done by 
 *    "ifconfig irda0 down" 
 */
static int irport_net_close(struct net_device *dev)
{
	struct irport_cb *self;
	int iobase;
	unsigned long flags;

	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);

	IRDA_ASSERT(dev != NULL, return -1;);
	self = (struct irport_cb *) dev->priv;

	IRDA_ASSERT(self != NULL, return -1;);

	iobase = self->io.sir_base;

	/* Stop device */
	netif_stop_queue(dev);
	
	/* Stop and remove instance of IrLAP */
	if (self->irlap)
		irlap_close(self->irlap);
	self->irlap = NULL;

	spin_lock_irqsave(&self->lock, flags);
	irport_stop(self);
	spin_unlock_irqrestore(&self->lock, flags);

	free_irq(self->io.irq, dev);

	return 0;
}

/*
 * Function irport_is_receiving (self)
 *
 *    Returns true is we are currently receiving data
 *
 */
static inline int irport_is_receiving(struct irport_cb *self)
{
	return (self->rx_buff.state != OUTSIDE_FRAME);
}

/*
 * Function irport_set_dtr_rts (tty, dtr, rts)
 *
 *    This function can be used by dongles etc. to set or reset the status
 *    of the dtr and rts lines
 */
static int irport_set_dtr_rts(struct net_device *dev, int dtr, int rts)
{
	struct irport_cb *self = dev->priv;
	int iobase;

	IRDA_ASSERT(self != NULL, return -1;);

	iobase = self->io.sir_base;

	if (dtr)
		dtr = UART_MCR_DTR;
	if (rts)
		rts = UART_MCR_RTS;

	outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR);

	return 0;
}

static int irport_raw_write(struct net_device *dev, __u8 *buf, int len)
{
	struct irport_cb *self = (struct irport_cb *) dev->priv;
	int actual = 0;
	int iobase;

	IRDA_ASSERT(self != NULL, return -1;);

	iobase = self->io.sir_base;

	/* Tx FIFO should be empty! */
	if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
		IRDA_DEBUG( 0, "%s(), failed, fifo not empty!\n", __FUNCTION__);
		return -1;
	}
        
	/* Fill FIFO with current frame */
	while (actual < len) {
		/* Transmit next byte */
		outb(buf[actual], iobase+UART_TX);
		actual++;
	}

	return actual;
}

/*
 * Function irport_net_ioctl (dev, rq, cmd)
 *
 *    Process IOCTL commands for this device
 *
 */
static int irport_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
	struct if_irda_req *irq = (struct if_irda_req *) rq;
	struct irport_cb *self;
	dongle_t *dongle;
	unsigned long flags;
	int ret = 0;

	IRDA_ASSERT(dev != NULL, return -1;);

	self = dev->priv;

	IRDA_ASSERT(self != NULL, return -1;);

	IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
	
	switch (cmd) {
	case SIOCSBANDWIDTH: /* Set bandwidth */
		if (!capable(CAP_NET_ADMIN))
			ret = -EPERM;
                else
			irda_task_execute(self, __irport_change_speed, NULL, 
					  NULL, (void *) irq->ifr_baudrate);
		break;
	case SIOCSDONGLE: /* Set dongle */
		if (!capable(CAP_NET_ADMIN)) {
			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);
		if (!dongle)
			break;
		
		dongle->set_mode    = NULL;
		dongle->read        = NULL;
		dongle->write       = irport_raw_write;
		dongle->set_dtr_rts = irport_set_dtr_rts;
		
		/* Now initialize the dongle!  */
		dongle->issue->open(dongle, &self->qos);
		
		/* Reset dongle */
		irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, 
				  NULL);	

		/* Make dongle available to driver only now to avoid
		 * race conditions - Jean II */
		self->dongle = dongle;
		break;
	case SIOCSMEDIABUSY: /* Set media busy */
		if (!capable(CAP_NET_ADMIN)) {
			ret = -EPERM;
			break;
		}

		irda_device_set_media_busy(self->netdev, TRUE);
		break;
	case SIOCGRECEIVING: /* Check if we are receiving right now */
		irq->ifr_receiving = irport_is_receiving(self);
		break;
	case SIOCSDTRRTS:
		if (!capable(CAP_NET_ADMIN)) {
			ret = -EPERM;
			break;
		}

		/* No real need to lock... */
		spin_lock_irqsave(&self->lock, flags);
		irport_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
		spin_unlock_irqrestore(&self->lock, flags);
		break;
	default:
		ret = -EOPNOTSUPP;
	}
	
	return ret;
}

static struct net_device_stats *irport_net_get_stats(struct net_device *dev)
{
	struct irport_cb *self = (struct irport_cb *) dev->priv;
	
	return &self->stats;
}

static int __init irport_init(void)
{
 	int i;

 	for (i=0; (io[i] < 2000) && (i < 4); i++) {
 		if (irport_open(i, io[i], irq[i]) != NULL)
 			return 0;
 	}
	/* 
	 * Maybe something failed, but we can still be usable for FIR drivers 
	 */
 	return 0;
}

/*
 * Function irport_cleanup ()
 *
 *    Close all configured ports
 *
 */
static void __exit irport_cleanup(void)
{
 	int i;

        IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);

	for (i=0; i < 4; i++) {
 		if (dev_self[i])
 			irport_close(dev_self[i]);
 	}
}

MODULE_PARM(io, "1-4i");
MODULE_PARM_DESC(io, "Base I/O addresses");
MODULE_PARM(irq, "1-4i");
MODULE_PARM_DESC(irq, "IRQ lines");

MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode");
MODULE_LICENSE("GPL");

module_init(irport_init);
module_exit(irport_cleanup);

