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

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

