/*********************************************************************
 *
 * Filename:      ircomm_tty.c
 * Version:       1.0
 * Description:   IrCOMM serial TTY driver
 * Status:        Experimental.
 * Author:        Dag Brattli <dagb@cs.uit.no>
 * Created at:    Sun Jun  6 21:00:56 1999
 * Modified at:   Wed Feb 23 00:09:02 2000
 * Modified by:   Dag Brattli <dagb@cs.uit.no>
 * Sources:       serial.c and previous IrCOMM work by Takahide Higuchi
 *
 *     Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
 *     Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
 *
 *     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
 *
 ********************************************************************/

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/termios.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/interrupt.h>
#include <linux/device.h>		/* for MODULE_ALIAS_CHARDEV_MAJOR */

#include <asm/uaccess.h>

#include <net/irda/irda.h>
#include <net/irda/irmod.h>

#include <net/irda/ircomm_core.h>
#include <net/irda/ircomm_param.h>
#include <net/irda/ircomm_tty_attach.h>
#include <net/irda/ircomm_tty.h>

static int ircomm_tty_install(struct tty_driver *driver,
		struct tty_struct *tty);
static int  ircomm_tty_open(struct tty_struct *tty, struct file *filp);
static void ircomm_tty_close(struct tty_struct * tty, struct file *filp);
static int  ircomm_tty_write(struct tty_struct * tty,
			     const unsigned char *buf, int count);
static int  ircomm_tty_write_room(struct tty_struct *tty);
static void ircomm_tty_throttle(struct tty_struct *tty);
static void ircomm_tty_unthrottle(struct tty_struct *tty);
static int  ircomm_tty_chars_in_buffer(struct tty_struct *tty);
static void ircomm_tty_flush_buffer(struct tty_struct *tty);
static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch);
static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout);
static void ircomm_tty_hangup(struct tty_struct *tty);
static void ircomm_tty_do_softint(struct work_struct *work);
static void ircomm_tty_shutdown(struct ircomm_tty_cb *self);
static void ircomm_tty_stop(struct tty_struct *tty);

static int ircomm_tty_data_indication(void *instance, void *sap,
				      struct sk_buff *skb);
static int ircomm_tty_control_indication(void *instance, void *sap,
					 struct sk_buff *skb);
static void ircomm_tty_flow_indication(void *instance, void *sap,
				       LOCAL_FLOW cmd);
#ifdef CONFIG_PROC_FS
static const struct file_operations ircomm_tty_proc_fops;
#endif /* CONFIG_PROC_FS */
static struct tty_driver *driver;

static hashbin_t *ircomm_tty = NULL;

static const struct tty_operations ops = {
	.install	 = ircomm_tty_install,
	.open            = ircomm_tty_open,
	.close           = ircomm_tty_close,
	.write           = ircomm_tty_write,
	.write_room      = ircomm_tty_write_room,
	.chars_in_buffer = ircomm_tty_chars_in_buffer,
	.flush_buffer    = ircomm_tty_flush_buffer,
	.ioctl           = ircomm_tty_ioctl,	/* ircomm_tty_ioctl.c */
	.tiocmget        = ircomm_tty_tiocmget,	/* ircomm_tty_ioctl.c */
	.tiocmset        = ircomm_tty_tiocmset,	/* ircomm_tty_ioctl.c */
	.throttle        = ircomm_tty_throttle,
	.unthrottle      = ircomm_tty_unthrottle,
	.send_xchar      = ircomm_tty_send_xchar,
	.set_termios     = ircomm_tty_set_termios,
	.stop            = ircomm_tty_stop,
	.start           = ircomm_tty_start,
	.hangup          = ircomm_tty_hangup,
	.wait_until_sent = ircomm_tty_wait_until_sent,
#ifdef CONFIG_PROC_FS
	.proc_fops       = &ircomm_tty_proc_fops,
#endif /* CONFIG_PROC_FS */
};

static void ircomm_port_raise_dtr_rts(struct tty_port *port, int raise)
{
	struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb,
			port);
	/*
	 * Here, we use to lock those two guys, but as ircomm_param_request()
	 * does it itself, I don't see the point (and I see the deadlock).
	 * Jean II
	 */
	if (raise)
		self->settings.dte |= IRCOMM_RTS | IRCOMM_DTR;
	else
		self->settings.dte &= ~(IRCOMM_RTS | IRCOMM_DTR);

	ircomm_param_request(self, IRCOMM_DTE, TRUE);
}

static int ircomm_port_carrier_raised(struct tty_port *port)
{
	struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb,
			port);
	return self->settings.dce & IRCOMM_CD;
}

static const struct tty_port_operations ircomm_port_ops = {
	.dtr_rts = ircomm_port_raise_dtr_rts,
	.carrier_raised = ircomm_port_carrier_raised,
};

/*
 * Function ircomm_tty_init()
 *
 *    Init IrCOMM TTY layer/driver
 *
 */
static int __init ircomm_tty_init(void)
{
	driver = alloc_tty_driver(IRCOMM_TTY_PORTS);
	if (!driver)
		return -ENOMEM;
	ircomm_tty = hashbin_new(HB_LOCK);
	if (ircomm_tty == NULL) {
		IRDA_ERROR("%s(), can't allocate hashbin!\n", __func__);
		put_tty_driver(driver);
		return -ENOMEM;
	}

	driver->driver_name     = "ircomm";
	driver->name            = "ircomm";
	driver->major           = IRCOMM_TTY_MAJOR;
	driver->minor_start     = IRCOMM_TTY_MINOR;
	driver->type            = TTY_DRIVER_TYPE_SERIAL;
	driver->subtype         = SERIAL_TYPE_NORMAL;
	driver->init_termios    = tty_std_termios;
	driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
	driver->flags           = TTY_DRIVER_REAL_RAW;
	tty_set_operations(driver, &ops);
	if (tty_register_driver(driver)) {
		IRDA_ERROR("%s(): Couldn't register serial driver\n",
			   __func__);
		put_tty_driver(driver);
		return -1;
	}
	return 0;
}

static void __exit __ircomm_tty_cleanup(struct ircomm_tty_cb *self)
{
	IRDA_DEBUG(0, "%s()\n", __func__ );

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	ircomm_tty_shutdown(self);

	self->magic = 0;
	kfree(self);
}

/*
 * Function ircomm_tty_cleanup ()
 *
 *    Remove IrCOMM TTY layer/driver
 *
 */
static void __exit ircomm_tty_cleanup(void)
{
	int ret;

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

	ret = tty_unregister_driver(driver);
	if (ret) {
		IRDA_ERROR("%s(), failed to unregister driver\n",
			   __func__);
		return;
	}

	hashbin_delete(ircomm_tty, (FREE_FUNC) __ircomm_tty_cleanup);
	put_tty_driver(driver);
}

/*
 * Function ircomm_startup (self)
 *
 *
 *
 */
static int ircomm_tty_startup(struct ircomm_tty_cb *self)
{
	notify_t notify;
	int ret = -ENODEV;

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

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

	/* Check if already open */
	if (test_and_set_bit(ASYNCB_INITIALIZED, &self->port.flags)) {
		IRDA_DEBUG(2, "%s(), already open so break out!\n", __func__ );
		return 0;
	}

	/* Register with IrCOMM */
	irda_notify_init(&notify);
	/* These callbacks we must handle ourselves */
	notify.data_indication       = ircomm_tty_data_indication;
	notify.udata_indication      = ircomm_tty_control_indication;
	notify.flow_indication       = ircomm_tty_flow_indication;

	/* Use the ircomm_tty interface for these ones */
	notify.disconnect_indication = ircomm_tty_disconnect_indication;
	notify.connect_confirm       = ircomm_tty_connect_confirm;
	notify.connect_indication    = ircomm_tty_connect_indication;
	strlcpy(notify.name, "ircomm_tty", sizeof(notify.name));
	notify.instance = self;

	if (!self->ircomm) {
		self->ircomm = ircomm_open(&notify, self->service_type,
					   self->line);
	}
	if (!self->ircomm)
		goto err;

	self->slsap_sel = self->ircomm->slsap_sel;

	/* Connect IrCOMM link with remote device */
	ret = ircomm_tty_attach_cable(self);
	if (ret < 0) {
		IRDA_ERROR("%s(), error attaching cable!\n", __func__);
		goto err;
	}

	return 0;
err:
	clear_bit(ASYNCB_INITIALIZED, &self->port.flags);
	return ret;
}

/*
 * Function ircomm_block_til_ready (self, filp)
 *
 *
 *
 */
static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
		struct tty_struct *tty, struct file *filp)
{
	struct tty_port *port = &self->port;
	DECLARE_WAITQUEUE(wait, current);
	int		retval;
	int		do_clocal = 0, extra_count = 0;
	unsigned long	flags;

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

	/*
	 * If non-blocking mode is set, or the port is not enabled,
	 * then make the check up front and then exit.
	 */
	if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
		/* nonblock mode is set or port is not enabled */
		port->flags |= ASYNC_NORMAL_ACTIVE;
		IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ );
		return 0;
	}

	if (tty->termios.c_cflag & CLOCAL) {
		IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __func__ );
		do_clocal = 1;
	}

	/* Wait for carrier detect and the line to become
	 * free (i.e., not in use by the callout).  While we are in
	 * this loop, port->count is dropped by one, so that
	 * mgsl_close() knows when to free things.  We restore it upon
	 * exit, either normal or abnormal.
	 */

	retval = 0;
	add_wait_queue(&port->open_wait, &wait);

	IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
	      __FILE__, __LINE__, tty->driver->name, port->count);

	spin_lock_irqsave(&port->lock, flags);
	if (!tty_hung_up_p(filp)) {
		extra_count = 1;
		port->count--;
	}
	spin_unlock_irqrestore(&port->lock, flags);
	port->blocked_open++;

	while (1) {
		if (tty->termios.c_cflag & CBAUD)
			tty_port_raise_dtr_rts(port);

		current->state = TASK_INTERRUPTIBLE;

		if (tty_hung_up_p(filp) ||
		    !test_bit(ASYNCB_INITIALIZED, &port->flags)) {
			retval = (port->flags & ASYNC_HUP_NOTIFY) ?
					-EAGAIN : -ERESTARTSYS;
			break;
		}

		/*
		 * Check if link is ready now. Even if CLOCAL is
		 * specified, we cannot return before the IrCOMM link is
		 * ready
		 */
		if (!test_bit(ASYNCB_CLOSING, &port->flags) &&
		    (do_clocal || tty_port_carrier_raised(port)) &&
		    self->state == IRCOMM_TTY_READY)
		{
			break;
		}

		if (signal_pending(current)) {
			retval = -ERESTARTSYS;
			break;
		}

		IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
		      __FILE__, __LINE__, tty->driver->name, port->count);

		schedule();
	}

	__set_current_state(TASK_RUNNING);
	remove_wait_queue(&port->open_wait, &wait);

	if (extra_count) {
		/* ++ is not atomic, so this should be protected - Jean II */
		spin_lock_irqsave(&port->lock, flags);
		port->count++;
		spin_unlock_irqrestore(&port->lock, flags);
	}
	port->blocked_open--;

	IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
	      __FILE__, __LINE__, tty->driver->name, port->count);

	if (!retval)
		port->flags |= ASYNC_NORMAL_ACTIVE;

	return retval;
}


static int ircomm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
{
	struct ircomm_tty_cb *self;
	unsigned int line = tty->index;

	/* Check if instance already exists */
	self = hashbin_lock_find(ircomm_tty, line, NULL);
	if (!self) {
		/* No, so make new instance */
		self = kzalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL);
		if (self == NULL) {
			IRDA_ERROR("%s(), kmalloc failed!\n", __func__);
			return -ENOMEM;
		}

		tty_port_init(&self->port);
		self->port.ops = &ircomm_port_ops;
		self->magic = IRCOMM_TTY_MAGIC;
		self->flow = FLOW_STOP;

		self->line = line;
		INIT_WORK(&self->tqueue, ircomm_tty_do_softint);
		self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED;
		self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED;

		/* Init some important stuff */
		init_timer(&self->watchdog_timer);
		spin_lock_init(&self->spinlock);

		/*
		 * Force TTY into raw mode by default which is usually what
		 * we want for IrCOMM and IrLPT. This way applications will
		 * not have to twiddle with printcap etc.
		 *
		 * Note this is completely usafe and doesn't work properly
		 */
		tty->termios.c_iflag = 0;
		tty->termios.c_oflag = 0;

		/* Insert into hash */
		hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL);
	}

	tty->driver_data = self;

	return tty_port_install(&self->port, driver, tty);
}

/*
 * Function ircomm_tty_open (tty, filp)
 *
 *    This routine is called when a particular tty device is opened. This
 *    routine is mandatory; if this routine is not filled in, the attempted
 *    open will fail with ENODEV.
 */
static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
{
	struct ircomm_tty_cb *self = tty->driver_data;
	unsigned long	flags;
	int ret;

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

	/* ++ is not atomic, so this should be protected - Jean II */
	spin_lock_irqsave(&self->port.lock, flags);
	self->port.count++;
	spin_unlock_irqrestore(&self->port.lock, flags);
	tty_port_tty_set(&self->port, tty);

	IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name,
		   self->line, self->port.count);

	/* Not really used by us, but lets do it anyway */
	tty->low_latency = (self->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;

	/*
	 * If the port is the middle of closing, bail out now
	 */
	if (tty_hung_up_p(filp) ||
	    test_bit(ASYNCB_CLOSING, &self->port.flags)) {

		/* Hm, why are we blocking on ASYNC_CLOSING if we
		 * do return -EAGAIN/-ERESTARTSYS below anyway?
		 * IMHO it's either not needed in the first place
		 * or for some reason we need to make sure the async
		 * closing has been finished - if so, wouldn't we
		 * probably better sleep uninterruptible?
		 */

		if (wait_event_interruptible(self->port.close_wait,
				!test_bit(ASYNCB_CLOSING, &self->port.flags))) {
			IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
				     __func__);
			return -ERESTARTSYS;
		}

#ifdef SERIAL_DO_RESTART
		return (self->port.flags & ASYNC_HUP_NOTIFY) ?
			-EAGAIN : -ERESTARTSYS;
#else
		return -EAGAIN;
#endif
	}

	/* Check if this is a "normal" ircomm device, or an irlpt device */
	if (self->line < 0x10) {
		self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE;
		self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */
		/* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */
		self->settings.dce = IRCOMM_CTS | IRCOMM_CD | IRCOMM_DSR | IRCOMM_RI; /* Default line settings */
		IRDA_DEBUG(2, "%s(), IrCOMM device\n", __func__ );
	} else {
		IRDA_DEBUG(2, "%s(), IrLPT device\n", __func__ );
		self->service_type = IRCOMM_3_WIRE_RAW;
		self->settings.service_type = IRCOMM_3_WIRE_RAW; /* Default */
	}

	ret = ircomm_tty_startup(self);
	if (ret)
		return ret;

	ret = ircomm_tty_block_til_ready(self, tty, filp);
	if (ret) {
		IRDA_DEBUG(2,
		      "%s(), returning after block_til_ready with %d\n", __func__ ,
		      ret);

		return ret;
	}
	return 0;
}

/*
 * Function ircomm_tty_close (tty, filp)
 *
 *    This routine is called when a particular tty device is closed.
 *
 */
static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
	struct tty_port *port = &self->port;

	IRDA_DEBUG(0, "%s()\n", __func__ );

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	if (tty_port_close_start(port, tty, filp) == 0)
		return;

	ircomm_tty_shutdown(self);

	tty_driver_flush_buffer(tty);

	tty_port_close_end(port, tty);
	tty_port_tty_set(port, NULL);
}

/*
 * Function ircomm_tty_flush_buffer (tty)
 *
 *
 *
 */
static void ircomm_tty_flush_buffer(struct tty_struct *tty)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	/*
	 * Let do_softint() do this to avoid race condition with
	 * do_softint() ;-)
	 */
	schedule_work(&self->tqueue);
}

/*
 * Function ircomm_tty_do_softint (work)
 *
 *    We use this routine to give the write wakeup to the user at at a
 *    safe time (as fast as possible after write have completed). This
 *    can be compared to the Tx interrupt.
 */
static void ircomm_tty_do_softint(struct work_struct *work)
{
	struct ircomm_tty_cb *self =
		container_of(work, struct ircomm_tty_cb, tqueue);
	struct tty_struct *tty;
	unsigned long flags;
	struct sk_buff *skb, *ctrl_skb;

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

	if (!self || self->magic != IRCOMM_TTY_MAGIC)
		return;

	tty = tty_port_tty_get(&self->port);
	if (!tty)
		return;

	/* Unlink control buffer */
	spin_lock_irqsave(&self->spinlock, flags);

	ctrl_skb = self->ctrl_skb;
	self->ctrl_skb = NULL;

	spin_unlock_irqrestore(&self->spinlock, flags);

	/* Flush control buffer if any */
	if(ctrl_skb) {
		if(self->flow == FLOW_START)
			ircomm_control_request(self->ircomm, ctrl_skb);
		/* Drop reference count - see ircomm_ttp_data_request(). */
		dev_kfree_skb(ctrl_skb);
	}

	if (tty->hw_stopped)
		goto put;

	/* Unlink transmit buffer */
	spin_lock_irqsave(&self->spinlock, flags);

	skb = self->tx_skb;
	self->tx_skb = NULL;

	spin_unlock_irqrestore(&self->spinlock, flags);

	/* Flush transmit buffer if any */
	if (skb) {
		ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, skb, NULL);
		/* Drop reference count - see ircomm_ttp_data_request(). */
		dev_kfree_skb(skb);
	}

	/* Check if user (still) wants to be waken up */
	tty_wakeup(tty);
put:
	tty_kref_put(tty);
}

/*
 * Function ircomm_tty_write (tty, buf, count)
 *
 *    This routine is called by the kernel to write a series of characters
 *    to the tty device. The characters may come from user space or kernel
 *    space. This routine will return the number of characters actually
 *    accepted for writing. This routine is mandatory.
 */
static int ircomm_tty_write(struct tty_struct *tty,
			    const unsigned char *buf, int count)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
	unsigned long flags;
	struct sk_buff *skb;
	int tailroom = 0;
	int len = 0;
	int size;

	IRDA_DEBUG(2, "%s(), count=%d, hw_stopped=%d\n", __func__ , count,
		   tty->hw_stopped);

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

	/* We may receive packets from the TTY even before we have finished
	 * our setup. Not cool.
	 * The problem is that we don't know the final header and data size
	 * to create the proper skb, so any skb we would create would have
	 * bogus header and data size, so need care.
	 * We use a bogus header size to safely detect this condition.
	 * Another problem is that hw_stopped was set to 0 way before it
	 * should be, so we would drop this skb. It should now be fixed.
	 * One option is to not accept data until we are properly setup.
	 * But, I suspect that when it happens, the ppp line discipline
	 * just "drops" the data, which might screw up connect scripts.
	 * The second option is to create a "safe skb", with large header
	 * and small size (see ircomm_tty_open() for values).
	 * We just need to make sure that when the real values get filled,
	 * we don't mess up the original "safe skb" (see tx_data_size).
	 * Jean II */
	if (self->max_header_size == IRCOMM_TTY_HDR_UNINITIALISED) {
		IRDA_DEBUG(1, "%s() : not initialised\n", __func__);
#ifdef IRCOMM_NO_TX_BEFORE_INIT
		/* We didn't consume anything, TTY will retry */
		return 0;
#endif
	}

	if (count < 1)
		return 0;

	/* Protect our manipulation of self->tx_skb and related */
	spin_lock_irqsave(&self->spinlock, flags);

	/* Fetch current transmit buffer */
	skb = self->tx_skb;

	/*
	 * Send out all the data we get, possibly as multiple fragmented
	 * frames, but this will only happen if the data is larger than the
	 * max data size. The normal case however is just the opposite, and
	 * this function may be called multiple times, and will then actually
	 * defragment the data and send it out as one packet as soon as
	 * possible, but at a safer point in time
	 */
	while (count) {
		size = count;

		/* Adjust data size to the max data size */
		if (size > self->max_data_size)
			size = self->max_data_size;

		/*
		 * Do we already have a buffer ready for transmit, or do
		 * we need to allocate a new frame
		 */
		if (skb) {
			/*
			 * Any room for more data at the end of the current
			 * transmit buffer? Cannot use skb_tailroom, since
			 * dev_alloc_skb gives us a larger skb than we
			 * requested
			 * Note : use tx_data_size, because max_data_size
			 * may have changed and we don't want to overwrite
			 * the skb. - Jean II
			 */
			if ((tailroom = (self->tx_data_size - skb->len)) > 0) {
				/* Adjust data to tailroom */
				if (size > tailroom)
					size = tailroom;
			} else {
				/*
				 * Current transmit frame is full, so break
				 * out, so we can send it as soon as possible
				 */
				break;
			}
		} else {
			/* Prepare a full sized frame */
			skb = alloc_skb(self->max_data_size+
					self->max_header_size,
					GFP_ATOMIC);
			if (!skb) {
				spin_unlock_irqrestore(&self->spinlock, flags);
				return -ENOBUFS;
			}
			skb_reserve(skb, self->max_header_size);
			self->tx_skb = skb;
			/* Remember skb size because max_data_size may
			 * change later on - Jean II */
			self->tx_data_size = self->max_data_size;
		}

		/* Copy data */
		memcpy(skb_put(skb,size), buf + len, size);

		count -= size;
		len += size;
	}

	spin_unlock_irqrestore(&self->spinlock, flags);

	/*
	 * Schedule a new thread which will transmit the frame as soon
	 * as possible, but at a safe point in time. We do this so the
	 * "user" can give us data multiple times, as PPP does (because of
	 * its 256 byte tx buffer). We will then defragment and send out
	 * all this data as one single packet.
	 */
	schedule_work(&self->tqueue);

	return len;
}

/*
 * Function ircomm_tty_write_room (tty)
 *
 *    This routine returns the numbers of characters the tty driver will
 *    accept for queuing to be written. This number is subject to change as
 *    output buffers get emptied, or if the output flow control is acted.
 */
static int ircomm_tty_write_room(struct tty_struct *tty)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
	unsigned long flags;
	int ret;

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

#ifdef IRCOMM_NO_TX_BEFORE_INIT
	/* max_header_size tells us if the channel is initialised or not. */
	if (self->max_header_size == IRCOMM_TTY_HDR_UNINITIALISED)
		/* Don't bother us yet */
		return 0;
#endif

	/* Check if we are allowed to transmit any data.
	 * hw_stopped is the regular flow control.
	 * Jean II */
	if (tty->hw_stopped)
		ret = 0;
	else {
		spin_lock_irqsave(&self->spinlock, flags);
		if (self->tx_skb)
			ret = self->tx_data_size - self->tx_skb->len;
		else
			ret = self->max_data_size;
		spin_unlock_irqrestore(&self->spinlock, flags);
	}
	IRDA_DEBUG(2, "%s(), ret=%d\n", __func__ , ret);

	return ret;
}

/*
 * Function ircomm_tty_wait_until_sent (tty, timeout)
 *
 *    This routine waits until the device has written out all of the
 *    characters in its transmitter FIFO.
 */
static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
	unsigned long orig_jiffies, poll_time;
	unsigned long flags;

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

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	orig_jiffies = jiffies;

	/* Set poll time to 200 ms */
	poll_time = IRDA_MIN(timeout, msecs_to_jiffies(200));

	spin_lock_irqsave(&self->spinlock, flags);
	while (self->tx_skb && self->tx_skb->len) {
		spin_unlock_irqrestore(&self->spinlock, flags);
		schedule_timeout_interruptible(poll_time);
		spin_lock_irqsave(&self->spinlock, flags);
		if (signal_pending(current))
			break;
		if (timeout && time_after(jiffies, orig_jiffies + timeout))
			break;
	}
	spin_unlock_irqrestore(&self->spinlock, flags);
	current->state = TASK_RUNNING;
}

/*
 * Function ircomm_tty_throttle (tty)
 *
 *    This routine notifies the tty driver that input buffers for the line
 *    discipline are close to full, and it should somehow signal that no
 *    more characters should be sent to the tty.
 */
static void ircomm_tty_throttle(struct tty_struct *tty)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;

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

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	/* Software flow control? */
	if (I_IXOFF(tty))
		ircomm_tty_send_xchar(tty, STOP_CHAR(tty));

	/* Hardware flow control? */
	if (tty->termios.c_cflag & CRTSCTS) {
		self->settings.dte &= ~IRCOMM_RTS;
		self->settings.dte |= IRCOMM_DELTA_RTS;

		ircomm_param_request(self, IRCOMM_DTE, TRUE);
	}

	ircomm_flow_request(self->ircomm, FLOW_STOP);
}

/*
 * Function ircomm_tty_unthrottle (tty)
 *
 *    This routine notifies the tty drivers that it should signals that
 *    characters can now be sent to the tty without fear of overrunning the
 *    input buffers of the line disciplines.
 */
static void ircomm_tty_unthrottle(struct tty_struct *tty)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;

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

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	/* Using software flow control? */
	if (I_IXOFF(tty)) {
		ircomm_tty_send_xchar(tty, START_CHAR(tty));
	}

	/* Using hardware flow control? */
	if (tty->termios.c_cflag & CRTSCTS) {
		self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS);

		ircomm_param_request(self, IRCOMM_DTE, TRUE);
		IRDA_DEBUG(1, "%s(), FLOW_START\n", __func__ );
	}
	ircomm_flow_request(self->ircomm, FLOW_START);
}

/*
 * Function ircomm_tty_chars_in_buffer (tty)
 *
 *    Indicates if there are any data in the buffer
 *
 */
static int ircomm_tty_chars_in_buffer(struct tty_struct *tty)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
	unsigned long flags;
	int len = 0;

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

	spin_lock_irqsave(&self->spinlock, flags);

	if (self->tx_skb)
		len = self->tx_skb->len;

	spin_unlock_irqrestore(&self->spinlock, flags);

	return len;
}

static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
{
	unsigned long flags;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	IRDA_DEBUG(0, "%s()\n", __func__ );

	if (!test_and_clear_bit(ASYNCB_INITIALIZED, &self->port.flags))
		return;

	ircomm_tty_detach_cable(self);

	spin_lock_irqsave(&self->spinlock, flags);

	del_timer(&self->watchdog_timer);

	/* Free parameter buffer */
	if (self->ctrl_skb) {
		dev_kfree_skb(self->ctrl_skb);
		self->ctrl_skb = NULL;
	}

	/* Free transmit buffer */
	if (self->tx_skb) {
		dev_kfree_skb(self->tx_skb);
		self->tx_skb = NULL;
	}

	if (self->ircomm) {
		ircomm_close(self->ircomm);
		self->ircomm = NULL;
	}

	spin_unlock_irqrestore(&self->spinlock, flags);
}

/*
 * Function ircomm_tty_hangup (tty)
 *
 *    This routine notifies the tty driver that it should hangup the tty
 *    device.
 *
 */
static void ircomm_tty_hangup(struct tty_struct *tty)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
	struct tty_port *port = &self->port;
	unsigned long	flags;

	IRDA_DEBUG(0, "%s()\n", __func__ );

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	/* ircomm_tty_flush_buffer(tty); */
	ircomm_tty_shutdown(self);

	spin_lock_irqsave(&port->lock, flags);
	port->flags &= ~ASYNC_NORMAL_ACTIVE;
	if (port->tty) {
		set_bit(TTY_IO_ERROR, &port->tty->flags);
		tty_kref_put(port->tty);
	}
	port->tty = NULL;
	port->count = 0;
	spin_unlock_irqrestore(&port->lock, flags);

	wake_up_interruptible(&port->open_wait);
}

/*
 * Function ircomm_tty_send_xchar (tty, ch)
 *
 *    This routine is used to send a high-priority XON/XOFF character to
 *    the device.
 */
static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch)
{
	IRDA_DEBUG(0, "%s(), not impl\n", __func__ );
}

/*
 * Function ircomm_tty_start (tty)
 *
 *    This routine notifies the tty driver that it resume sending
 *    characters to the tty device.
 */
void ircomm_tty_start(struct tty_struct *tty)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;

	ircomm_flow_request(self->ircomm, FLOW_START);
}

/*
 * Function ircomm_tty_stop (tty)
 *
 *     This routine notifies the tty driver that it should stop outputting
 *     characters to the tty device.
 */
static void ircomm_tty_stop(struct tty_struct *tty)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	ircomm_flow_request(self->ircomm, FLOW_STOP);
}

/*
 * Function ircomm_check_modem_status (self)
 *
 *    Check for any changes in the DCE's line settings. This function should
 *    be called whenever the dce parameter settings changes, to update the
 *    flow control settings and other things
 */
void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
{
	struct tty_struct *tty;
	int status;

	IRDA_DEBUG(0, "%s()\n", __func__ );

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	tty = tty_port_tty_get(&self->port);

	status = self->settings.dce;

	if (status & IRCOMM_DCE_DELTA_ANY) {
		/*wake_up_interruptible(&self->delta_msr_wait);*/
	}
	if ((self->port.flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) {
		IRDA_DEBUG(2,
			   "%s(), ircomm%d CD now %s...\n", __func__ , self->line,
			   (status & IRCOMM_CD) ? "on" : "off");

		if (status & IRCOMM_CD) {
			wake_up_interruptible(&self->port.open_wait);
		} else {
			IRDA_DEBUG(2,
				   "%s(), Doing serial hangup..\n", __func__ );
			if (tty)
				tty_hangup(tty);

			/* Hangup will remote the tty, so better break out */
			goto put;
		}
	}
	if (tty && tty_port_cts_enabled(&self->port)) {
		if (tty->hw_stopped) {
			if (status & IRCOMM_CTS) {
				IRDA_DEBUG(2,
					   "%s(), CTS tx start...\n", __func__ );
				tty->hw_stopped = 0;

				/* Wake up processes blocked on open */
				wake_up_interruptible(&self->port.open_wait);

				schedule_work(&self->tqueue);
				goto put;
			}
		} else {
			if (!(status & IRCOMM_CTS)) {
				IRDA_DEBUG(2,
					   "%s(), CTS tx stop...\n", __func__ );
				tty->hw_stopped = 1;
			}
		}
	}
put:
	tty_kref_put(tty);
}

/*
 * Function ircomm_tty_data_indication (instance, sap, skb)
 *
 *    Handle incoming data, and deliver it to the line discipline
 *
 */
static int ircomm_tty_data_indication(void *instance, void *sap,
				      struct sk_buff *skb)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
	struct tty_struct *tty;

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

	IRDA_ASSERT(self != NULL, return -1;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
	IRDA_ASSERT(skb != NULL, return -1;);

	tty = tty_port_tty_get(&self->port);
	if (!tty) {
		IRDA_DEBUG(0, "%s(), no tty!\n", __func__ );
		return 0;
	}

	/*
	 * If we receive data when hardware is stopped then something is wrong.
	 * We try to poll the peers line settings to check if we are up todate.
	 * Devices like WinCE can do this, and since they don't send any
	 * params, we can just as well declare the hardware for running.
	 */
	if (tty->hw_stopped && (self->flow == FLOW_START)) {
		IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ );
		ircomm_param_request(self, IRCOMM_POLL, TRUE);

		/* We can just as well declare the hardware for running */
		ircomm_tty_send_initial_parameters(self);
		ircomm_tty_link_established(self);
	}

	/*
	 * Use flip buffer functions since the code may be called from interrupt
	 * context
	 */
	tty_insert_flip_string(tty, skb->data, skb->len);
	tty_flip_buffer_push(tty);
	tty_kref_put(tty);

	/* No need to kfree_skb - see ircomm_ttp_data_indication() */

	return 0;
}

/*
 * Function ircomm_tty_control_indication (instance, sap, skb)
 *
 *    Parse all incoming parameters (easy!)
 *
 */
static int ircomm_tty_control_indication(void *instance, void *sap,
					 struct sk_buff *skb)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
	int clen;

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

	IRDA_ASSERT(self != NULL, return -1;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
	IRDA_ASSERT(skb != NULL, return -1;);

	clen = skb->data[0];

	irda_param_extract_all(self, skb->data+1, IRDA_MIN(skb->len-1, clen),
			       &ircomm_param_info);

	/* No need to kfree_skb - see ircomm_control_indication() */

	return 0;
}

/*
 * Function ircomm_tty_flow_indication (instance, sap, cmd)
 *
 *    This function is called by IrTTP when it wants us to slow down the
 *    transmission of data. We just mark the hardware as stopped, and wait
 *    for IrTTP to notify us that things are OK again.
 */
static void ircomm_tty_flow_indication(void *instance, void *sap,
				       LOCAL_FLOW cmd)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
	struct tty_struct *tty;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	tty = tty_port_tty_get(&self->port);

	switch (cmd) {
	case FLOW_START:
		IRDA_DEBUG(2, "%s(), hw start!\n", __func__ );
		if (tty)
			tty->hw_stopped = 0;

		/* ircomm_tty_do_softint will take care of the rest */
		schedule_work(&self->tqueue);
		break;
	default:  /* If we get here, something is very wrong, better stop */
	case FLOW_STOP:
		IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ );
		if (tty)
			tty->hw_stopped = 1;
		break;
	}

	tty_kref_put(tty);
	self->flow = cmd;
}

#ifdef CONFIG_PROC_FS
static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m)
{
	struct tty_struct *tty;
	char sep;

	seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]);

	seq_puts(m, "Service type: ");
	if (self->service_type & IRCOMM_9_WIRE)
		seq_puts(m, "9_WIRE");
	else if (self->service_type & IRCOMM_3_WIRE)
		seq_puts(m, "3_WIRE");
	else if (self->service_type & IRCOMM_3_WIRE_RAW)
		seq_puts(m, "3_WIRE_RAW");
	else
		seq_puts(m, "No common service type!\n");
	seq_putc(m, '\n');

	seq_printf(m, "Port name: %s\n", self->settings.port_name);

	seq_printf(m, "DTE status:");
	sep = ' ';
	if (self->settings.dte & IRCOMM_RTS) {
		seq_printf(m, "%cRTS", sep);
		sep = '|';
	}
	if (self->settings.dte & IRCOMM_DTR) {
		seq_printf(m, "%cDTR", sep);
		sep = '|';
	}
	seq_putc(m, '\n');

	seq_puts(m, "DCE status:");
	sep = ' ';
	if (self->settings.dce & IRCOMM_CTS) {
		seq_printf(m, "%cCTS", sep);
		sep = '|';
	}
	if (self->settings.dce & IRCOMM_DSR) {
		seq_printf(m, "%cDSR", sep);
		sep = '|';
	}
	if (self->settings.dce & IRCOMM_CD) {
		seq_printf(m, "%cCD", sep);
		sep = '|';
	}
	if (self->settings.dce & IRCOMM_RI) {
		seq_printf(m, "%cRI", sep);
		sep = '|';
	}
	seq_putc(m, '\n');

	seq_puts(m, "Configuration: ");
	if (!self->settings.null_modem)
		seq_puts(m, "DTE <-> DCE\n");
	else
		seq_puts(m, "DTE <-> DTE (null modem emulation)\n");

	seq_printf(m, "Data rate: %d\n", self->settings.data_rate);

	seq_puts(m, "Flow control:");
	sep = ' ';
	if (self->settings.flow_control & IRCOMM_XON_XOFF_IN) {
		seq_printf(m, "%cXON_XOFF_IN", sep);
		sep = '|';
	}
	if (self->settings.flow_control & IRCOMM_XON_XOFF_OUT) {
		seq_printf(m, "%cXON_XOFF_OUT", sep);
		sep = '|';
	}
	if (self->settings.flow_control & IRCOMM_RTS_CTS_IN) {
		seq_printf(m, "%cRTS_CTS_IN", sep);
		sep = '|';
	}
	if (self->settings.flow_control & IRCOMM_RTS_CTS_OUT) {
		seq_printf(m, "%cRTS_CTS_OUT", sep);
		sep = '|';
	}
	if (self->settings.flow_control & IRCOMM_DSR_DTR_IN) {
		seq_printf(m, "%cDSR_DTR_IN", sep);
		sep = '|';
	}
	if (self->settings.flow_control & IRCOMM_DSR_DTR_OUT) {
		seq_printf(m, "%cDSR_DTR_OUT", sep);
		sep = '|';
	}
	if (self->settings.flow_control & IRCOMM_ENQ_ACK_IN) {
		seq_printf(m, "%cENQ_ACK_IN", sep);
		sep = '|';
	}
	if (self->settings.flow_control & IRCOMM_ENQ_ACK_OUT) {
		seq_printf(m, "%cENQ_ACK_OUT", sep);
		sep = '|';
	}
	seq_putc(m, '\n');

	seq_puts(m, "Flags:");
	sep = ' ';
	if (tty_port_cts_enabled(&self->port)) {
		seq_printf(m, "%cASYNC_CTS_FLOW", sep);
		sep = '|';
	}
	if (self->port.flags & ASYNC_CHECK_CD) {
		seq_printf(m, "%cASYNC_CHECK_CD", sep);
		sep = '|';
	}
	if (self->port.flags & ASYNC_INITIALIZED) {
		seq_printf(m, "%cASYNC_INITIALIZED", sep);
		sep = '|';
	}
	if (self->port.flags & ASYNC_LOW_LATENCY) {
		seq_printf(m, "%cASYNC_LOW_LATENCY", sep);
		sep = '|';
	}
	if (self->port.flags & ASYNC_CLOSING) {
		seq_printf(m, "%cASYNC_CLOSING", sep);
		sep = '|';
	}
	if (self->port.flags & ASYNC_NORMAL_ACTIVE) {
		seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep);
		sep = '|';
	}
	seq_putc(m, '\n');

	seq_printf(m, "Role: %s\n", self->client ? "client" : "server");
	seq_printf(m, "Open count: %d\n", self->port.count);
	seq_printf(m, "Max data size: %d\n", self->max_data_size);
	seq_printf(m, "Max header size: %d\n", self->max_header_size);

	tty = tty_port_tty_get(&self->port);
	if (tty) {
		seq_printf(m, "Hardware: %s\n",
			       tty->hw_stopped ? "Stopped" : "Running");
		tty_kref_put(tty);
	}
}

static int ircomm_tty_proc_show(struct seq_file *m, void *v)
{
	struct ircomm_tty_cb *self;
	unsigned long flags;

	spin_lock_irqsave(&ircomm_tty->hb_spinlock, flags);

	self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty);
	while (self != NULL) {
		if (self->magic != IRCOMM_TTY_MAGIC)
			break;

		ircomm_tty_line_info(self, m);
		self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty);
	}
	spin_unlock_irqrestore(&ircomm_tty->hb_spinlock, flags);
	return 0;
}

static int ircomm_tty_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, ircomm_tty_proc_show, NULL);
}

static const struct file_operations ircomm_tty_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= ircomm_tty_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};
#endif /* CONFIG_PROC_FS */

MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
MODULE_DESCRIPTION("IrCOMM serial TTY driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(IRCOMM_TTY_MAJOR);

module_init(ircomm_tty_init);
module_exit(ircomm_tty_cleanup);
