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

	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_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
 *
 */
static 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 acquired.
	 * 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)
 *
 *    Interrupt handler
 */
static irqreturn_t irport_interrupt(int irq, void *dev_id) 
{
	struct net_device *dev = dev_id;
	struct irport_cb *self;
	int boguscount = 0;
	int iobase;
	int iir, lsr;
	int handled = 0;

	self = 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 < ARRAY_SIZE(dev_self)); 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 < ARRAY_SIZE(dev_self); i++) {
 		if (dev_self[i])
 			irport_close(dev_self[i]);
 	}
}

module_param_array(io, int, NULL, 0);
MODULE_PARM_DESC(io, "Base I/O addresses");
module_param_array(irq, int, NULL, 0);
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);

