/*********************************************************************
 *
 * Filename:      irttp.c
 * Version:       1.2
 * Description:   Tiny Transport Protocol (TTP) implementation
 * Status:        Stable
 * Author:        Dag Brattli <dagb@cs.uit.no>
 * Created at:    Sun Aug 31 20:14:31 1997
 * Modified at:   Wed Jan  5 11:31:27 2000
 * Modified by:   Dag Brattli <dagb@cs.uit.no>
 *
 *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
 *     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.
 *
 *     Neither Dag Brattli nor University of Tromsø admit liability nor
 *     provide warranty for any of this software. This material is
 *     provided "AS-IS" and at no charge.
 *
 ********************************************************************/

#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/export.h>

#include <asm/byteorder.h>
#include <asm/unaligned.h>

#include <net/irda/irda.h>
#include <net/irda/irlap.h>
#include <net/irda/irlmp.h>
#include <net/irda/parameters.h>
#include <net/irda/irttp.h>

static struct irttp_cb *irttp;

static void __irttp_close_tsap(struct tsap_cb *self);

static int irttp_data_indication(void *instance, void *sap,
				 struct sk_buff *skb);
static int irttp_udata_indication(void *instance, void *sap,
				  struct sk_buff *skb);
static void irttp_disconnect_indication(void *instance, void *sap,
					LM_REASON reason, struct sk_buff *);
static void irttp_connect_indication(void *instance, void *sap,
				     struct qos_info *qos, __u32 max_sdu_size,
				     __u8 header_size, struct sk_buff *skb);
static void irttp_connect_confirm(void *instance, void *sap,
				  struct qos_info *qos, __u32 max_sdu_size,
				  __u8 header_size, struct sk_buff *skb);
static void irttp_run_tx_queue(struct tsap_cb *self);
static void irttp_run_rx_queue(struct tsap_cb *self);

static void irttp_flush_queues(struct tsap_cb *self);
static void irttp_fragment_skb(struct tsap_cb *self, struct sk_buff *skb);
static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self);
static void irttp_todo_expired(unsigned long data);
static int irttp_param_max_sdu_size(void *instance, irda_param_t *param,
				    int get);

static void irttp_flow_indication(void *instance, void *sap, LOCAL_FLOW flow);
static void irttp_status_indication(void *instance,
				    LINK_STATUS link, LOCK_STATUS lock);

/* Information for parsing parameters in IrTTP */
static pi_minor_info_t pi_minor_call_table[] = {
	{ NULL, 0 },                                             /* 0x00 */
	{ irttp_param_max_sdu_size, PV_INTEGER | PV_BIG_ENDIAN } /* 0x01 */
};
static pi_major_info_t pi_major_call_table[] = { { pi_minor_call_table, 2 } };
static pi_param_info_t param_info = { pi_major_call_table, 1, 0x0f, 4 };

/************************ GLOBAL PROCEDURES ************************/

/*
 * Function irttp_init (void)
 *
 *    Initialize the IrTTP layer. Called by module initialization code
 *
 */
int __init irttp_init(void)
{
	irttp = kzalloc(sizeof(struct irttp_cb), GFP_KERNEL);
	if (irttp == NULL)
		return -ENOMEM;

	irttp->magic = TTP_MAGIC;

	irttp->tsaps = hashbin_new(HB_LOCK);
	if (!irttp->tsaps) {
		net_err_ratelimited("%s: can't allocate IrTTP hashbin!\n",
				    __func__);
		kfree(irttp);
		return -ENOMEM;
	}

	return 0;
}

/*
 * Function irttp_cleanup (void)
 *
 *    Called by module destruction/cleanup code
 *
 */
void irttp_cleanup(void)
{
	/* Check for main structure */
	IRDA_ASSERT(irttp->magic == TTP_MAGIC, return;);

	/*
	 *  Delete hashbin and close all TSAP instances in it
	 */
	hashbin_delete(irttp->tsaps, (FREE_FUNC) __irttp_close_tsap);

	irttp->magic = 0;

	/* De-allocate main structure */
	kfree(irttp);

	irttp = NULL;
}

/*************************** SUBROUTINES ***************************/

/*
 * Function irttp_start_todo_timer (self, timeout)
 *
 *    Start todo timer.
 *
 * Made it more effient and unsensitive to race conditions - Jean II
 */
static inline void irttp_start_todo_timer(struct tsap_cb *self, int timeout)
{
	/* Set new value for timer */
	mod_timer(&self->todo_timer, jiffies + timeout);
}

/*
 * Function irttp_todo_expired (data)
 *
 *    Todo timer has expired!
 *
 * One of the restriction of the timer is that it is run only on the timer
 * interrupt which run every 10ms. This mean that even if you set the timer
 * with a delay of 0, it may take up to 10ms before it's run.
 * So, to minimise latency and keep cache fresh, we try to avoid using
 * it as much as possible.
 * Note : we can't use tasklets, because they can't be asynchronously
 * killed (need user context), and we can't guarantee that here...
 * Jean II
 */
static void irttp_todo_expired(unsigned long data)
{
	struct tsap_cb *self = (struct tsap_cb *) data;

	/* Check that we still exist */
	if (!self || self->magic != TTP_TSAP_MAGIC)
		return;

	pr_debug("%s(instance=%p)\n", __func__, self);

	/* Try to make some progress, especially on Tx side - Jean II */
	irttp_run_rx_queue(self);
	irttp_run_tx_queue(self);

	/* Check if time for disconnect */
	if (test_bit(0, &self->disconnect_pend)) {
		/* Check if it's possible to disconnect yet */
		if (skb_queue_empty(&self->tx_queue)) {
			/* Make sure disconnect is not pending anymore */
			clear_bit(0, &self->disconnect_pend);	/* FALSE */

			/* Note : self->disconnect_skb may be NULL */
			irttp_disconnect_request(self, self->disconnect_skb,
						 P_NORMAL);
			self->disconnect_skb = NULL;
		} else {
			/* Try again later */
			irttp_start_todo_timer(self, HZ/10);

			/* No reason to try and close now */
			return;
		}
	}

	/* Check if it's closing time */
	if (self->close_pend)
		/* Finish cleanup */
		irttp_close_tsap(self);
}

/*
 * Function irttp_flush_queues (self)
 *
 *     Flushes (removes all frames) in transitt-buffer (tx_list)
 */
static void irttp_flush_queues(struct tsap_cb *self)
{
	struct sk_buff *skb;

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

	/* Deallocate frames waiting to be sent */
	while ((skb = skb_dequeue(&self->tx_queue)) != NULL)
		dev_kfree_skb(skb);

	/* Deallocate received frames */
	while ((skb = skb_dequeue(&self->rx_queue)) != NULL)
		dev_kfree_skb(skb);

	/* Deallocate received fragments */
	while ((skb = skb_dequeue(&self->rx_fragments)) != NULL)
		dev_kfree_skb(skb);
}

/*
 * Function irttp_reassemble (self)
 *
 *    Makes a new (continuous) skb of all the fragments in the fragment
 *    queue
 *
 */
static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self)
{
	struct sk_buff *skb, *frag;
	int n = 0;  /* Fragment index */

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

	pr_debug("%s(), self->rx_sdu_size=%d\n", __func__,
		 self->rx_sdu_size);

	skb = dev_alloc_skb(TTP_HEADER + self->rx_sdu_size);
	if (!skb)
		return NULL;

	/*
	 * Need to reserve space for TTP header in case this skb needs to
	 * be requeued in case delivery failes
	 */
	skb_reserve(skb, TTP_HEADER);
	skb_put(skb, self->rx_sdu_size);

	/*
	 *  Copy all fragments to a new buffer
	 */
	while ((frag = skb_dequeue(&self->rx_fragments)) != NULL) {
		skb_copy_to_linear_data_offset(skb, n, frag->data, frag->len);
		n += frag->len;

		dev_kfree_skb(frag);
	}

	pr_debug("%s(), frame len=%d, rx_sdu_size=%d, rx_max_sdu_size=%d\n",
		 __func__, n, self->rx_sdu_size, self->rx_max_sdu_size);
	/* Note : irttp_run_rx_queue() calculate self->rx_sdu_size
	 * by summing the size of all fragments, so we should always
	 * have n == self->rx_sdu_size, except in cases where we
	 * droped the last fragment (when self->rx_sdu_size exceed
	 * self->rx_max_sdu_size), where n < self->rx_sdu_size.
	 * Jean II */
	IRDA_ASSERT(n <= self->rx_sdu_size, n = self->rx_sdu_size;);

	/* Set the new length */
	skb_trim(skb, n);

	self->rx_sdu_size = 0;

	return skb;
}

/*
 * Function irttp_fragment_skb (skb)
 *
 *    Fragments a frame and queues all the fragments for transmission
 *
 */
static inline void irttp_fragment_skb(struct tsap_cb *self,
				      struct sk_buff *skb)
{
	struct sk_buff *frag;
	__u8 *frame;

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

	/*
	 *  Split frame into a number of segments
	 */
	while (skb->len > self->max_seg_size) {
		pr_debug("%s(), fragmenting ...\n", __func__);

		/* Make new segment */
		frag = alloc_skb(self->max_seg_size+self->max_header_size,
				 GFP_ATOMIC);
		if (!frag)
			return;

		skb_reserve(frag, self->max_header_size);

		/* Copy data from the original skb into this fragment. */
		skb_copy_from_linear_data(skb, skb_put(frag, self->max_seg_size),
			      self->max_seg_size);

		/* Insert TTP header, with the more bit set */
		frame = skb_push(frag, TTP_HEADER);
		frame[0] = TTP_MORE;

		/* Hide the copied data from the original skb */
		skb_pull(skb, self->max_seg_size);

		/* Queue fragment */
		skb_queue_tail(&self->tx_queue, frag);
	}
	/* Queue what is left of the original skb */
	pr_debug("%s(), queuing last segment\n", __func__);

	frame = skb_push(skb, TTP_HEADER);
	frame[0] = 0x00; /* Clear more bit */

	/* Queue fragment */
	skb_queue_tail(&self->tx_queue, skb);
}

/*
 * Function irttp_param_max_sdu_size (self, param)
 *
 *    Handle the MaxSduSize parameter in the connect frames, this function
 *    will be called both when this parameter needs to be inserted into, and
 *    extracted from the connect frames
 */
static int irttp_param_max_sdu_size(void *instance, irda_param_t *param,
				    int get)
{
	struct tsap_cb *self;

	self = instance;

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

	if (get)
		param->pv.i = self->tx_max_sdu_size;
	else
		self->tx_max_sdu_size = param->pv.i;

	pr_debug("%s(), MaxSduSize=%d\n", __func__, param->pv.i);

	return 0;
}

/*************************** CLIENT CALLS ***************************/
/************************** LMP CALLBACKS **************************/
/* Everything is happily mixed up. Waiting for next clean up - Jean II */

/*
 * Initialization, that has to be done on new tsap
 * instance allocation and on duplication
 */
static void irttp_init_tsap(struct tsap_cb *tsap)
{
	spin_lock_init(&tsap->lock);
	init_timer(&tsap->todo_timer);

	skb_queue_head_init(&tsap->rx_queue);
	skb_queue_head_init(&tsap->tx_queue);
	skb_queue_head_init(&tsap->rx_fragments);
}

/*
 * Function irttp_open_tsap (stsap, notify)
 *
 *    Create TSAP connection endpoint,
 */
struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
{
	struct tsap_cb *self;
	struct lsap_cb *lsap;
	notify_t ttp_notify;

	IRDA_ASSERT(irttp->magic == TTP_MAGIC, return NULL;);

	/* The IrLMP spec (IrLMP 1.1 p10) says that we have the right to
	 * use only 0x01-0x6F. Of course, we can use LSAP_ANY as well.
	 * JeanII */
	if ((stsap_sel != LSAP_ANY) &&
	   ((stsap_sel < 0x01) || (stsap_sel >= 0x70))) {
		pr_debug("%s(), invalid tsap!\n", __func__);
		return NULL;
	}

	self = kzalloc(sizeof(struct tsap_cb), GFP_ATOMIC);
	if (self == NULL)
		return NULL;

	/* Initialize internal objects */
	irttp_init_tsap(self);

	/* Initialise todo timer */
	self->todo_timer.data     = (unsigned long) self;
	self->todo_timer.function = &irttp_todo_expired;

	/* Initialize callbacks for IrLMP to use */
	irda_notify_init(&ttp_notify);
	ttp_notify.connect_confirm = irttp_connect_confirm;
	ttp_notify.connect_indication = irttp_connect_indication;
	ttp_notify.disconnect_indication = irttp_disconnect_indication;
	ttp_notify.data_indication = irttp_data_indication;
	ttp_notify.udata_indication = irttp_udata_indication;
	ttp_notify.flow_indication = irttp_flow_indication;
	if (notify->status_indication != NULL)
		ttp_notify.status_indication = irttp_status_indication;
	ttp_notify.instance = self;
	strncpy(ttp_notify.name, notify->name, NOTIFY_MAX_NAME);

	self->magic = TTP_TSAP_MAGIC;
	self->connected = FALSE;

	/*
	 *  Create LSAP at IrLMP layer
	 */
	lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0);
	if (lsap == NULL) {
		pr_debug("%s: unable to allocate LSAP!!\n", __func__);
		__irttp_close_tsap(self);
		return NULL;
	}

	/*
	 *  If user specified LSAP_ANY as source TSAP selector, then IrLMP
	 *  will replace it with whatever source selector which is free, so
	 *  the stsap_sel we have might not be valid anymore
	 */
	self->stsap_sel = lsap->slsap_sel;
	pr_debug("%s(), stsap_sel=%02x\n", __func__, self->stsap_sel);

	self->notify = *notify;
	self->lsap = lsap;

	hashbin_insert(irttp->tsaps, (irda_queue_t *) self, (long) self, NULL);

	if (credit > TTP_RX_MAX_CREDIT)
		self->initial_credit = TTP_RX_MAX_CREDIT;
	else
		self->initial_credit = credit;

	return self;
}
EXPORT_SYMBOL(irttp_open_tsap);

/*
 * Function irttp_close (handle)
 *
 *    Remove an instance of a TSAP. This function should only deal with the
 *    deallocation of the TSAP, and resetting of the TSAPs values;
 *
 */
static void __irttp_close_tsap(struct tsap_cb *self)
{
	/* First make sure we're connected. */
	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);

	irttp_flush_queues(self);

	del_timer(&self->todo_timer);

	/* This one won't be cleaned up if we are disconnect_pend + close_pend
	 * and we receive a disconnect_indication */
	if (self->disconnect_skb)
		dev_kfree_skb(self->disconnect_skb);

	self->connected = FALSE;
	self->magic = ~TTP_TSAP_MAGIC;

	kfree(self);
}

/*
 * Function irttp_close (self)
 *
 *    Remove TSAP from list of all TSAPs and then deallocate all resources
 *    associated with this TSAP
 *
 * Note : because we *free* the tsap structure, it is the responsibility
 * of the caller to make sure we are called only once and to deal with
 * possible race conditions. - Jean II
 */
int irttp_close_tsap(struct tsap_cb *self)
{
	struct tsap_cb *tsap;

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

	/* Make sure tsap has been disconnected */
	if (self->connected) {
		/* Check if disconnect is not pending */
		if (!test_bit(0, &self->disconnect_pend)) {
			net_warn_ratelimited("%s: TSAP still connected!\n",
					     __func__);
			irttp_disconnect_request(self, NULL, P_NORMAL);
		}
		self->close_pend = TRUE;
		irttp_start_todo_timer(self, HZ/10);

		return 0; /* Will be back! */
	}

	tsap = hashbin_remove(irttp->tsaps, (long) self, NULL);

	IRDA_ASSERT(tsap == self, return -1;);

	/* Close corresponding LSAP */
	if (self->lsap) {
		irlmp_close_lsap(self->lsap);
		self->lsap = NULL;
	}

	__irttp_close_tsap(self);

	return 0;
}
EXPORT_SYMBOL(irttp_close_tsap);

/*
 * Function irttp_udata_request (self, skb)
 *
 *    Send unreliable data on this TSAP
 *
 */
int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb)
{
	int ret;

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

	/* Take shortcut on zero byte packets */
	if (skb->len == 0) {
		ret = 0;
		goto err;
	}

	/* Check that nothing bad happens */
	if (!self->connected) {
		net_warn_ratelimited("%s(), Not connected\n", __func__);
		ret = -ENOTCONN;
		goto err;
	}

	if (skb->len > self->max_seg_size) {
		net_err_ratelimited("%s(), UData is too large for IrLAP!\n",
				    __func__);
		ret = -EMSGSIZE;
		goto err;
	}

	irlmp_udata_request(self->lsap, skb);
	self->stats.tx_packets++;

	return 0;

err:
	dev_kfree_skb(skb);
	return ret;
}
EXPORT_SYMBOL(irttp_udata_request);


/*
 * Function irttp_data_request (handle, skb)
 *
 *    Queue frame for transmission. If SAR is enabled, fragement the frame
 *    and queue the fragments for transmission
 */
int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb)
{
	__u8 *frame;
	int ret;

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

	pr_debug("%s() : queue len = %d\n", __func__,
		 skb_queue_len(&self->tx_queue));

	/* Take shortcut on zero byte packets */
	if (skb->len == 0) {
		ret = 0;
		goto err;
	}

	/* Check that nothing bad happens */
	if (!self->connected) {
		net_warn_ratelimited("%s: Not connected\n", __func__);
		ret = -ENOTCONN;
		goto err;
	}

	/*
	 *  Check if SAR is disabled, and the frame is larger than what fits
	 *  inside an IrLAP frame
	 */
	if ((self->tx_max_sdu_size == 0) && (skb->len > self->max_seg_size)) {
		net_err_ratelimited("%s: SAR disabled, and data is too large for IrLAP!\n",
				    __func__);
		ret = -EMSGSIZE;
		goto err;
	}

	/*
	 *  Check if SAR is enabled, and the frame is larger than the
	 *  TxMaxSduSize
	 */
	if ((self->tx_max_sdu_size != 0) &&
	    (self->tx_max_sdu_size != TTP_SAR_UNBOUND) &&
	    (skb->len > self->tx_max_sdu_size)) {
		net_err_ratelimited("%s: SAR enabled, but data is larger than TxMaxSduSize!\n",
				    __func__);
		ret = -EMSGSIZE;
		goto err;
	}
	/*
	 *  Check if transmit queue is full
	 */
	if (skb_queue_len(&self->tx_queue) >= TTP_TX_MAX_QUEUE) {
		/*
		 *  Give it a chance to empty itself
		 */
		irttp_run_tx_queue(self);

		/* Drop packet. This error code should trigger the caller
		 * to resend the data in the client code - Jean II */
		ret = -ENOBUFS;
		goto err;
	}

	/* Queue frame, or queue frame segments */
	if ((self->tx_max_sdu_size == 0) || (skb->len < self->max_seg_size)) {
		/* Queue frame */
		IRDA_ASSERT(skb_headroom(skb) >= TTP_HEADER, return -1;);
		frame = skb_push(skb, TTP_HEADER);
		frame[0] = 0x00; /* Clear more bit */

		skb_queue_tail(&self->tx_queue, skb);
	} else {
		/*
		 *  Fragment the frame, this function will also queue the
		 *  fragments, we don't care about the fact the transmit
		 *  queue may be overfilled by all the segments for a little
		 *  while
		 */
		irttp_fragment_skb(self, skb);
	}

	/* Check if we can accept more data from client */
	if ((!self->tx_sdu_busy) &&
	    (skb_queue_len(&self->tx_queue) > TTP_TX_HIGH_THRESHOLD)) {
		/* Tx queue filling up, so stop client. */
		if (self->notify.flow_indication) {
			self->notify.flow_indication(self->notify.instance,
						     self, FLOW_STOP);
		}
		/* self->tx_sdu_busy is the state of the client.
		 * Update state after notifying client to avoid
		 * race condition with irttp_flow_indication().
		 * If the queue empty itself after our test but before
		 * we set the flag, we will fix ourselves below in
		 * irttp_run_tx_queue().
		 * Jean II */
		self->tx_sdu_busy = TRUE;
	}

	/* Try to make some progress */
	irttp_run_tx_queue(self);

	return 0;

err:
	dev_kfree_skb(skb);
	return ret;
}
EXPORT_SYMBOL(irttp_data_request);

/*
 * Function irttp_run_tx_queue (self)
 *
 *    Transmit packets queued for transmission (if possible)
 *
 */
static void irttp_run_tx_queue(struct tsap_cb *self)
{
	struct sk_buff *skb;
	unsigned long flags;
	int n;

	pr_debug("%s() : send_credit = %d, queue_len = %d\n",
		 __func__,
		 self->send_credit, skb_queue_len(&self->tx_queue));

	/* Get exclusive access to the tx queue, otherwise don't touch it */
	if (irda_lock(&self->tx_queue_lock) == FALSE)
		return;

	/* Try to send out frames as long as we have credits
	 * and as long as LAP is not full. If LAP is full, it will
	 * poll us through irttp_flow_indication() - Jean II */
	while ((self->send_credit > 0) &&
	       (!irlmp_lap_tx_queue_full(self->lsap)) &&
	       (skb = skb_dequeue(&self->tx_queue))) {
		/*
		 *  Since we can transmit and receive frames concurrently,
		 *  the code below is a critical region and we must assure that
		 *  nobody messes with the credits while we update them.
		 */
		spin_lock_irqsave(&self->lock, flags);

		n = self->avail_credit;
		self->avail_credit = 0;

		/* Only room for 127 credits in frame */
		if (n > 127) {
			self->avail_credit = n-127;
			n = 127;
		}
		self->remote_credit += n;
		self->send_credit--;

		spin_unlock_irqrestore(&self->lock, flags);

		/*
		 *  More bit must be set by the data_request() or fragment()
		 *  functions
		 */
		skb->data[0] |= (n & 0x7f);

		/* Detach from socket.
		 * The current skb has a reference to the socket that sent
		 * it (skb->sk). When we pass it to IrLMP, the skb will be
		 * stored in in IrLAP (self->wx_list). When we are within
		 * IrLAP, we lose the notion of socket, so we should not
		 * have a reference to a socket. So, we drop it here.
		 *
		 * Why does it matter ?
		 * When the skb is freed (kfree_skb), if it is associated
		 * with a socket, it release buffer space on the socket
		 * (through sock_wfree() and sock_def_write_space()).
		 * If the socket no longer exist, we may crash. Hard.
		 * When we close a socket, we make sure that associated packets
		 * in IrTTP are freed. However, we have no way to cancel
		 * the packet that we have passed to IrLAP. So, if a packet
		 * remains in IrLAP (retry on the link or else) after we
		 * close the socket, we are dead !
		 * Jean II */
		if (skb->sk != NULL) {
			/* IrSOCK application, IrOBEX, ... */
			skb_orphan(skb);
		}
			/* IrCOMM over IrTTP, IrLAN, ... */

		/* Pass the skb to IrLMP - done */
		irlmp_data_request(self->lsap, skb);
		self->stats.tx_packets++;
	}

	/* Check if we can accept more frames from client.
	 * We don't want to wait until the todo timer to do that, and we
	 * can't use tasklets (grr...), so we are obliged to give control
	 * to client. That's ok, this test will be true not too often
	 * (max once per LAP window) and we are called from places
	 * where we can spend a bit of time doing stuff. - Jean II */
	if ((self->tx_sdu_busy) &&
	    (skb_queue_len(&self->tx_queue) < TTP_TX_LOW_THRESHOLD) &&
	    (!self->close_pend)) {
		if (self->notify.flow_indication)
			self->notify.flow_indication(self->notify.instance,
						     self, FLOW_START);

		/* self->tx_sdu_busy is the state of the client.
		 * We don't really have a race here, but it's always safer
		 * to update our state after the client - Jean II */
		self->tx_sdu_busy = FALSE;
	}

	/* Reset lock */
	self->tx_queue_lock = 0;
}

/*
 * Function irttp_give_credit (self)
 *
 *    Send a dataless flowdata TTP-PDU and give available credit to peer
 *    TSAP
 */
static inline void irttp_give_credit(struct tsap_cb *self)
{
	struct sk_buff *tx_skb = NULL;
	unsigned long flags;
	int n;

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

	pr_debug("%s() send=%d,avail=%d,remote=%d\n",
		 __func__,
		 self->send_credit, self->avail_credit, self->remote_credit);

	/* Give credit to peer */
	tx_skb = alloc_skb(TTP_MAX_HEADER, GFP_ATOMIC);
	if (!tx_skb)
		return;

	/* Reserve space for LMP, and LAP header */
	skb_reserve(tx_skb, LMP_MAX_HEADER);

	/*
	 *  Since we can transmit and receive frames concurrently,
	 *  the code below is a critical region and we must assure that
	 *  nobody messes with the credits while we update them.
	 */
	spin_lock_irqsave(&self->lock, flags);

	n = self->avail_credit;
	self->avail_credit = 0;

	/* Only space for 127 credits in frame */
	if (n > 127) {
		self->avail_credit = n - 127;
		n = 127;
	}
	self->remote_credit += n;

	spin_unlock_irqrestore(&self->lock, flags);

	skb_put(tx_skb, 1);
	tx_skb->data[0] = (__u8) (n & 0x7f);

	irlmp_data_request(self->lsap, tx_skb);
	self->stats.tx_packets++;
}

/*
 * Function irttp_udata_indication (instance, sap, skb)
 *
 *    Received some unit-data (unreliable)
 *
 */
static int irttp_udata_indication(void *instance, void *sap,
				  struct sk_buff *skb)
{
	struct tsap_cb *self;
	int err;

	self = instance;

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

	self->stats.rx_packets++;

	/* Just pass data to layer above */
	if (self->notify.udata_indication) {
		err = self->notify.udata_indication(self->notify.instance,
						    self, skb);
		/* Same comment as in irttp_do_data_indication() */
		if (!err)
			return 0;
	}
	/* Either no handler, or handler returns an error */
	dev_kfree_skb(skb);

	return 0;
}

/*
 * Function irttp_data_indication (instance, sap, skb)
 *
 *    Receive segment from IrLMP.
 *
 */
static int irttp_data_indication(void *instance, void *sap,
				 struct sk_buff *skb)
{
	struct tsap_cb *self;
	unsigned long flags;
	int n;

	self = instance;

	n = skb->data[0] & 0x7f;     /* Extract the credits */

	self->stats.rx_packets++;

	/*  Deal with inbound credit
	 *  Since we can transmit and receive frames concurrently,
	 *  the code below is a critical region and we must assure that
	 *  nobody messes with the credits while we update them.
	 */
	spin_lock_irqsave(&self->lock, flags);
	self->send_credit += n;
	if (skb->len > 1)
		self->remote_credit--;
	spin_unlock_irqrestore(&self->lock, flags);

	/*
	 *  Data or dataless packet? Dataless frames contains only the
	 *  TTP_HEADER.
	 */
	if (skb->len > 1) {
		/*
		 *  We don't remove the TTP header, since we must preserve the
		 *  more bit, so the defragment routing knows what to do
		 */
		skb_queue_tail(&self->rx_queue, skb);
	} else {
		/* Dataless flowdata TTP-PDU */
		dev_kfree_skb(skb);
	}


	/* Push data to the higher layer.
	 * We do it synchronously because running the todo timer for each
	 * receive packet would be too much overhead and latency.
	 * By passing control to the higher layer, we run the risk that
	 * it may take time or grab a lock. Most often, the higher layer
	 * will only put packet in a queue.
	 * Anyway, packets are only dripping through the IrDA, so we can
	 * have time before the next packet.
	 * Further, we are run from NET_BH, so the worse that can happen is
	 * us missing the optimal time to send back the PF bit in LAP.
	 * Jean II */
	irttp_run_rx_queue(self);

	/* We now give credits to peer in irttp_run_rx_queue().
	 * We need to send credit *NOW*, otherwise we are going
	 * to miss the next Tx window. The todo timer may take
	 * a while before it's run... - Jean II */

	/*
	 * If the peer device has given us some credits and we didn't have
	 * anyone from before, then we need to shedule the tx queue.
	 * We need to do that because our Tx have stopped (so we may not
	 * get any LAP flow indication) and the user may be stopped as
	 * well. - Jean II
	 */
	if (self->send_credit == n) {
		/* Restart pushing stuff to LAP */
		irttp_run_tx_queue(self);
		/* Note : we don't want to schedule the todo timer
		 * because it has horrible latency. No tasklets
		 * because the tasklet API is broken. - Jean II */
	}

	return 0;
}

/*
 * Function irttp_status_indication (self, reason)
 *
 *    Status_indication, just pass to the higher layer...
 *
 */
static void irttp_status_indication(void *instance,
				    LINK_STATUS link, LOCK_STATUS lock)
{
	struct tsap_cb *self;

	self = instance;

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

	/* Check if client has already closed the TSAP and gone away */
	if (self->close_pend)
		return;

	/*
	 *  Inform service user if he has requested it
	 */
	if (self->notify.status_indication != NULL)
		self->notify.status_indication(self->notify.instance,
					       link, lock);
	else
		pr_debug("%s(), no handler\n", __func__);
}

/*
 * Function irttp_flow_indication (self, reason)
 *
 *    Flow_indication : IrLAP tells us to send more data.
 *
 */
static void irttp_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
{
	struct tsap_cb *self;

	self = instance;

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

	pr_debug("%s(instance=%p)\n", __func__, self);

	/* We are "polled" directly from LAP, and the LAP want to fill
	 * its Tx window. We want to do our best to send it data, so that
	 * we maximise the window. On the other hand, we want to limit the
	 * amount of work here so that LAP doesn't hang forever waiting
	 * for packets. - Jean II */

	/* Try to send some packets. Currently, LAP calls us every time
	 * there is one free slot, so we will send only one packet.
	 * This allow the scheduler to do its round robin - Jean II */
	irttp_run_tx_queue(self);

	/* Note regarding the interraction with higher layer.
	 * irttp_run_tx_queue() may call the client when its queue
	 * start to empty, via notify.flow_indication(). Initially.
	 * I wanted this to happen in a tasklet, to avoid client
	 * grabbing the CPU, but we can't use tasklets safely. And timer
	 * is definitely too slow.
	 * This will happen only once per LAP window, and usually at
	 * the third packet (unless window is smaller). LAP is still
	 * doing mtt and sending first packet so it's sort of OK
	 * to do that. Jean II */

	/* If we need to send disconnect. try to do it now */
	if (self->disconnect_pend)
		irttp_start_todo_timer(self, 0);
}

/*
 * Function irttp_flow_request (self, command)
 *
 *    This function could be used by the upper layers to tell IrTTP to stop
 *    delivering frames if the receive queues are starting to get full, or
 *    to tell IrTTP to start delivering frames again.
 */
void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow)
{
	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);

	switch (flow) {
	case FLOW_STOP:
		pr_debug("%s(), flow stop\n", __func__);
		self->rx_sdu_busy = TRUE;
		break;
	case FLOW_START:
		pr_debug("%s(), flow start\n", __func__);
		self->rx_sdu_busy = FALSE;

		/* Client say he can accept more data, try to free our
		 * queues ASAP - Jean II */
		irttp_run_rx_queue(self);

		break;
	default:
		pr_debug("%s(), Unknown flow command!\n", __func__);
	}
}
EXPORT_SYMBOL(irttp_flow_request);

/*
 * Function irttp_connect_request (self, dtsap_sel, daddr, qos)
 *
 *    Try to connect to remote destination TSAP selector
 *
 */
int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
			  __u32 saddr, __u32 daddr,
			  struct qos_info *qos, __u32 max_sdu_size,
			  struct sk_buff *userdata)
{
	struct sk_buff *tx_skb;
	__u8 *frame;
	__u8 n;

	pr_debug("%s(), max_sdu_size=%d\n", __func__, max_sdu_size);

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

	if (self->connected) {
		if (userdata)
			dev_kfree_skb(userdata);
		return -EISCONN;
	}

	/* Any userdata supplied? */
	if (userdata == NULL) {
		tx_skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER,
				   GFP_ATOMIC);
		if (!tx_skb)
			return -ENOMEM;

		/* Reserve space for MUX_CONTROL and LAP header */
		skb_reserve(tx_skb, TTP_MAX_HEADER + TTP_SAR_HEADER);
	} else {
		tx_skb = userdata;
		/*
		 *  Check that the client has reserved enough space for
		 *  headers
		 */
		IRDA_ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER,
			{ dev_kfree_skb(userdata); return -1; });
	}

	/* Initialize connection parameters */
	self->connected = FALSE;
	self->avail_credit = 0;
	self->rx_max_sdu_size = max_sdu_size;
	self->rx_sdu_size = 0;
	self->rx_sdu_busy = FALSE;
	self->dtsap_sel = dtsap_sel;

	n = self->initial_credit;

	self->remote_credit = 0;
	self->send_credit = 0;

	/*
	 *  Give away max 127 credits for now
	 */
	if (n > 127) {
		self->avail_credit = n - 127;
		n = 127;
	}

	self->remote_credit = n;

	/* SAR enabled? */
	if (max_sdu_size > 0) {
		IRDA_ASSERT(skb_headroom(tx_skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER),
			{ dev_kfree_skb(tx_skb); return -1; });

		/* Insert SAR parameters */
		frame = skb_push(tx_skb, TTP_HEADER + TTP_SAR_HEADER);

		frame[0] = TTP_PARAMETERS | n;
		frame[1] = 0x04; /* Length */
		frame[2] = 0x01; /* MaxSduSize */
		frame[3] = 0x02; /* Value length */

		put_unaligned(cpu_to_be16((__u16) max_sdu_size),
			      (__be16 *)(frame+4));
	} else {
		/* Insert plain TTP header */
		frame = skb_push(tx_skb, TTP_HEADER);

		/* Insert initial credit in frame */
		frame[0] = n & 0x7f;
	}

	/* Connect with IrLMP. No QoS parameters for now */
	return irlmp_connect_request(self->lsap, dtsap_sel, saddr, daddr, qos,
				     tx_skb);
}
EXPORT_SYMBOL(irttp_connect_request);

/*
 * Function irttp_connect_confirm (handle, qos, skb)
 *
 *    Service user confirms TSAP connection with peer.
 *
 */
static void irttp_connect_confirm(void *instance, void *sap,
				  struct qos_info *qos, __u32 max_seg_size,
				  __u8 max_header_size, struct sk_buff *skb)
{
	struct tsap_cb *self;
	int parameters;
	int ret;
	__u8 plen;
	__u8 n;

	self = instance;

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

	self->max_seg_size = max_seg_size - TTP_HEADER;
	self->max_header_size = max_header_size + TTP_HEADER;

	/*
	 *  Check if we have got some QoS parameters back! This should be the
	 *  negotiated QoS for the link.
	 */
	if (qos) {
		pr_debug("IrTTP, Negotiated BAUD_RATE: %02x\n",
			 qos->baud_rate.bits);
		pr_debug("IrTTP, Negotiated BAUD_RATE: %d bps.\n",
			 qos->baud_rate.value);
	}

	n = skb->data[0] & 0x7f;

	pr_debug("%s(), Initial send_credit=%d\n", __func__, n);

	self->send_credit = n;
	self->tx_max_sdu_size = 0;
	self->connected = TRUE;

	parameters = skb->data[0] & 0x80;

	IRDA_ASSERT(skb->len >= TTP_HEADER, return;);
	skb_pull(skb, TTP_HEADER);

	if (parameters) {
		plen = skb->data[0];

		ret = irda_param_extract_all(self, skb->data+1,
					     IRDA_MIN(skb->len-1, plen),
					     &param_info);

		/* Any errors in the parameter list? */
		if (ret < 0) {
			net_warn_ratelimited("%s: error extracting parameters\n",
					     __func__);
			dev_kfree_skb(skb);

			/* Do not accept this connection attempt */
			return;
		}
		/* Remove parameters */
		skb_pull(skb, IRDA_MIN(skb->len, plen+1));
	}

	pr_debug("%s() send=%d,avail=%d,remote=%d\n", __func__,
		 self->send_credit, self->avail_credit, self->remote_credit);

	pr_debug("%s(), MaxSduSize=%d\n", __func__,
		 self->tx_max_sdu_size);

	if (self->notify.connect_confirm) {
		self->notify.connect_confirm(self->notify.instance, self, qos,
					     self->tx_max_sdu_size,
					     self->max_header_size, skb);
	} else
		dev_kfree_skb(skb);
}

/*
 * Function irttp_connect_indication (handle, skb)
 *
 *    Some other device is connecting to this TSAP
 *
 */
static void irttp_connect_indication(void *instance, void *sap,
		struct qos_info *qos, __u32 max_seg_size, __u8 max_header_size,
		struct sk_buff *skb)
{
	struct tsap_cb *self;
	struct lsap_cb *lsap;
	int parameters;
	int ret;
	__u8 plen;
	__u8 n;

	self = instance;

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

	lsap = sap;

	self->max_seg_size = max_seg_size - TTP_HEADER;
	self->max_header_size = max_header_size+TTP_HEADER;

	pr_debug("%s(), TSAP sel=%02x\n", __func__, self->stsap_sel);

	/* Need to update dtsap_sel if its equal to LSAP_ANY */
	self->dtsap_sel = lsap->dlsap_sel;

	n = skb->data[0] & 0x7f;

	self->send_credit = n;
	self->tx_max_sdu_size = 0;

	parameters = skb->data[0] & 0x80;

	IRDA_ASSERT(skb->len >= TTP_HEADER, return;);
	skb_pull(skb, TTP_HEADER);

	if (parameters) {
		plen = skb->data[0];

		ret = irda_param_extract_all(self, skb->data+1,
					     IRDA_MIN(skb->len-1, plen),
					     &param_info);

		/* Any errors in the parameter list? */
		if (ret < 0) {
			net_warn_ratelimited("%s: error extracting parameters\n",
					     __func__);
			dev_kfree_skb(skb);

			/* Do not accept this connection attempt */
			return;
		}

		/* Remove parameters */
		skb_pull(skb, IRDA_MIN(skb->len, plen+1));
	}

	if (self->notify.connect_indication) {
		self->notify.connect_indication(self->notify.instance, self,
						qos, self->tx_max_sdu_size,
						self->max_header_size, skb);
	} else
		dev_kfree_skb(skb);
}

/*
 * Function irttp_connect_response (handle, userdata)
 *
 *    Service user is accepting the connection, just pass it down to
 *    IrLMP!
 *
 */
int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
			   struct sk_buff *userdata)
{
	struct sk_buff *tx_skb;
	__u8 *frame;
	int ret;
	__u8 n;

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

	pr_debug("%s(), Source TSAP selector=%02x\n", __func__,
		 self->stsap_sel);

	/* Any userdata supplied? */
	if (userdata == NULL) {
		tx_skb = alloc_skb(TTP_MAX_HEADER + TTP_SAR_HEADER,
				   GFP_ATOMIC);
		if (!tx_skb)
			return -ENOMEM;

		/* Reserve space for MUX_CONTROL and LAP header */
		skb_reserve(tx_skb, TTP_MAX_HEADER + TTP_SAR_HEADER);
	} else {
		tx_skb = userdata;
		/*
		 *  Check that the client has reserved enough space for
		 *  headers
		 */
		IRDA_ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER,
			{ dev_kfree_skb(userdata); return -1; });
	}

	self->avail_credit = 0;
	self->remote_credit = 0;
	self->rx_max_sdu_size = max_sdu_size;
	self->rx_sdu_size = 0;
	self->rx_sdu_busy = FALSE;

	n = self->initial_credit;

	/* Frame has only space for max 127 credits (7 bits) */
	if (n > 127) {
		self->avail_credit = n - 127;
		n = 127;
	}

	self->remote_credit = n;
	self->connected = TRUE;

	/* SAR enabled? */
	if (max_sdu_size > 0) {
		IRDA_ASSERT(skb_headroom(tx_skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER),
			{ dev_kfree_skb(tx_skb); return -1; });

		/* Insert TTP header with SAR parameters */
		frame = skb_push(tx_skb, TTP_HEADER + TTP_SAR_HEADER);

		frame[0] = TTP_PARAMETERS | n;
		frame[1] = 0x04; /* Length */

		/* irda_param_insert(self, IRTTP_MAX_SDU_SIZE, frame+1,  */
/*				  TTP_SAR_HEADER, &param_info) */

		frame[2] = 0x01; /* MaxSduSize */
		frame[3] = 0x02; /* Value length */

		put_unaligned(cpu_to_be16((__u16) max_sdu_size),
			      (__be16 *)(frame+4));
	} else {
		/* Insert TTP header */
		frame = skb_push(tx_skb, TTP_HEADER);

		frame[0] = n & 0x7f;
	}

	ret = irlmp_connect_response(self->lsap, tx_skb);

	return ret;
}
EXPORT_SYMBOL(irttp_connect_response);

/*
 * Function irttp_dup (self, instance)
 *
 *    Duplicate TSAP, can be used by servers to confirm a connection on a
 *    new TSAP so it can keep listening on the old one.
 */
struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance)
{
	struct tsap_cb *new;
	unsigned long flags;

	/* Protect our access to the old tsap instance */
	spin_lock_irqsave(&irttp->tsaps->hb_spinlock, flags);

	/* Find the old instance */
	if (!hashbin_find(irttp->tsaps, (long) orig, NULL)) {
		pr_debug("%s(), unable to find TSAP\n", __func__);
		spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);
		return NULL;
	}

	/* Allocate a new instance */
	new = kmemdup(orig, sizeof(struct tsap_cb), GFP_ATOMIC);
	if (!new) {
		pr_debug("%s(), unable to kmalloc\n", __func__);
		spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);
		return NULL;
	}
	spin_lock_init(&new->lock);

	/* We don't need the old instance any more */
	spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);

	/* Try to dup the LSAP (may fail if we were too slow) */
	new->lsap = irlmp_dup(orig->lsap, new);
	if (!new->lsap) {
		pr_debug("%s(), dup failed!\n", __func__);
		kfree(new);
		return NULL;
	}

	/* Not everything should be copied */
	new->notify.instance = instance;

	/* Initialize internal objects */
	irttp_init_tsap(new);

	/* This is locked */
	hashbin_insert(irttp->tsaps, (irda_queue_t *) new, (long) new, NULL);

	return new;
}
EXPORT_SYMBOL(irttp_dup);

/*
 * Function irttp_disconnect_request (self)
 *
 *    Close this connection please! If priority is high, the queued data
 *    segments, if any, will be deallocated first
 *
 */
int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata,
			     int priority)
{
	int ret;

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

	/* Already disconnected? */
	if (!self->connected) {
		pr_debug("%s(), already disconnected!\n", __func__);
		if (userdata)
			dev_kfree_skb(userdata);
		return -1;
	}

	/* Disconnect already pending ?
	 * We need to use an atomic operation to prevent reentry. This
	 * function may be called from various context, like user, timer
	 * for following a disconnect_indication() (i.e. net_bh).
	 * Jean II */
	if (test_and_set_bit(0, &self->disconnect_pend)) {
		pr_debug("%s(), disconnect already pending\n",
			 __func__);
		if (userdata)
			dev_kfree_skb(userdata);

		/* Try to make some progress */
		irttp_run_tx_queue(self);
		return -1;
	}

	/*
	 *  Check if there is still data segments in the transmit queue
	 */
	if (!skb_queue_empty(&self->tx_queue)) {
		if (priority == P_HIGH) {
			/*
			 *  No need to send the queued data, if we are
			 *  disconnecting right now since the data will
			 *  not have any usable connection to be sent on
			 */
			pr_debug("%s(): High priority!!()\n", __func__);
			irttp_flush_queues(self);
		} else if (priority == P_NORMAL) {
			/*
			 *  Must delay disconnect until after all data segments
			 *  have been sent and the tx_queue is empty
			 */
			/* We'll reuse this one later for the disconnect */
			self->disconnect_skb = userdata;  /* May be NULL */

			irttp_run_tx_queue(self);

			irttp_start_todo_timer(self, HZ/10);
			return -1;
		}
	}
	/* Note : we don't need to check if self->rx_queue is full and the
	 * state of self->rx_sdu_busy because the disconnect response will
	 * be sent at the LMP level (so even if the peer has its Tx queue
	 * full of data). - Jean II */

	pr_debug("%s(), Disconnecting ...\n", __func__);
	self->connected = FALSE;

	if (!userdata) {
		struct sk_buff *tx_skb;
		tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
		if (!tx_skb)
			return -ENOMEM;

		/*
		 *  Reserve space for MUX and LAP header
		 */
		skb_reserve(tx_skb, LMP_MAX_HEADER);

		userdata = tx_skb;
	}
	ret = irlmp_disconnect_request(self->lsap, userdata);

	/* The disconnect is no longer pending */
	clear_bit(0, &self->disconnect_pend);	/* FALSE */

	return ret;
}
EXPORT_SYMBOL(irttp_disconnect_request);

/*
 * Function irttp_disconnect_indication (self, reason)
 *
 *    Disconnect indication, TSAP disconnected by peer?
 *
 */
static void irttp_disconnect_indication(void *instance, void *sap,
		LM_REASON reason, struct sk_buff *skb)
{
	struct tsap_cb *self;

	self = instance;

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

	/* Prevent higher layer to send more data */
	self->connected = FALSE;

	/* Check if client has already tried to close the TSAP */
	if (self->close_pend) {
		/* In this case, the higher layer is probably gone. Don't
		 * bother it and clean up the remains - Jean II */
		if (skb)
			dev_kfree_skb(skb);
		irttp_close_tsap(self);
		return;
	}

	/* If we are here, we assume that is the higher layer is still
	 * waiting for the disconnect notification and able to process it,
	 * even if he tried to disconnect. Otherwise, it would have already
	 * attempted to close the tsap and self->close_pend would be TRUE.
	 * Jean II */

	/* No need to notify the client if has already tried to disconnect */
	if (self->notify.disconnect_indication)
		self->notify.disconnect_indication(self->notify.instance, self,
						   reason, skb);
	else
		if (skb)
			dev_kfree_skb(skb);
}

/*
 * Function irttp_do_data_indication (self, skb)
 *
 *    Try to deliver reassembled skb to layer above, and requeue it if that
 *    for some reason should fail. We mark rx sdu as busy to apply back
 *    pressure is necessary.
 */
static void irttp_do_data_indication(struct tsap_cb *self, struct sk_buff *skb)
{
	int err;

	/* Check if client has already closed the TSAP and gone away */
	if (self->close_pend) {
		dev_kfree_skb(skb);
		return;
	}

	err = self->notify.data_indication(self->notify.instance, self, skb);

	/* Usually the layer above will notify that it's input queue is
	 * starting to get filled by using the flow request, but this may
	 * be difficult, so it can instead just refuse to eat it and just
	 * give an error back
	 */
	if (err) {
		pr_debug("%s() requeueing skb!\n", __func__);

		/* Make sure we take a break */
		self->rx_sdu_busy = TRUE;

		/* Need to push the header in again */
		skb_push(skb, TTP_HEADER);
		skb->data[0] = 0x00; /* Make sure MORE bit is cleared */

		/* Put skb back on queue */
		skb_queue_head(&self->rx_queue, skb);
	}
}

/*
 * Function irttp_run_rx_queue (self)
 *
 *     Check if we have any frames to be transmitted, or if we have any
 *     available credit to give away.
 */
static void irttp_run_rx_queue(struct tsap_cb *self)
{
	struct sk_buff *skb;
	int more = 0;

	pr_debug("%s() send=%d,avail=%d,remote=%d\n", __func__,
		 self->send_credit, self->avail_credit, self->remote_credit);

	/* Get exclusive access to the rx queue, otherwise don't touch it */
	if (irda_lock(&self->rx_queue_lock) == FALSE)
		return;

	/*
	 *  Reassemble all frames in receive queue and deliver them
	 */
	while (!self->rx_sdu_busy && (skb = skb_dequeue(&self->rx_queue))) {
		/* This bit will tell us if it's the last fragment or not */
		more = skb->data[0] & 0x80;

		/* Remove TTP header */
		skb_pull(skb, TTP_HEADER);

		/* Add the length of the remaining data */
		self->rx_sdu_size += skb->len;

		/*
		 * If SAR is disabled, or user has requested no reassembly
		 * of received fragments then we just deliver them
		 * immediately. This can be requested by clients that
		 * implements byte streams without any message boundaries
		 */
		if (self->rx_max_sdu_size == TTP_SAR_DISABLE) {
			irttp_do_data_indication(self, skb);
			self->rx_sdu_size = 0;

			continue;
		}

		/* Check if this is a fragment, and not the last fragment */
		if (more) {
			/*
			 *  Queue the fragment if we still are within the
			 *  limits of the maximum size of the rx_sdu
			 */
			if (self->rx_sdu_size <= self->rx_max_sdu_size) {
				pr_debug("%s(), queueing frag\n",
					 __func__);
				skb_queue_tail(&self->rx_fragments, skb);
			} else {
				/* Free the part of the SDU that is too big */
				dev_kfree_skb(skb);
			}
			continue;
		}
		/*
		 *  This is the last fragment, so time to reassemble!
		 */
		if ((self->rx_sdu_size <= self->rx_max_sdu_size) ||
		    (self->rx_max_sdu_size == TTP_SAR_UNBOUND)) {
			/*
			 * A little optimizing. Only queue the fragment if
			 * there are other fragments. Since if this is the
			 * last and only fragment, there is no need to
			 * reassemble :-)
			 */
			if (!skb_queue_empty(&self->rx_fragments)) {
				skb_queue_tail(&self->rx_fragments,
					       skb);

				skb = irttp_reassemble_skb(self);
			}

			/* Now we can deliver the reassembled skb */
			irttp_do_data_indication(self, skb);
		} else {
			pr_debug("%s(), Truncated frame\n", __func__);

			/* Free the part of the SDU that is too big */
			dev_kfree_skb(skb);

			/* Deliver only the valid but truncated part of SDU */
			skb = irttp_reassemble_skb(self);

			irttp_do_data_indication(self, skb);
		}
		self->rx_sdu_size = 0;
	}

	/*
	 * It's not trivial to keep track of how many credits are available
	 * by incrementing at each packet, because delivery may fail
	 * (irttp_do_data_indication() may requeue the frame) and because
	 * we need to take care of fragmentation.
	 * We want the other side to send up to initial_credit packets.
	 * We have some frames in our queues, and we have already allowed it
	 * to send remote_credit.
	 * No need to spinlock, write is atomic and self correcting...
	 * Jean II
	 */
	self->avail_credit = (self->initial_credit -
			      (self->remote_credit +
			       skb_queue_len(&self->rx_queue) +
			       skb_queue_len(&self->rx_fragments)));

	/* Do we have too much credits to send to peer ? */
	if ((self->remote_credit <= TTP_RX_MIN_CREDIT) &&
	    (self->avail_credit > 0)) {
		/* Send explicit credit frame */
		irttp_give_credit(self);
		/* Note : do *NOT* check if tx_queue is non-empty, that
		 * will produce deadlocks. I repeat : send a credit frame
		 * even if we have something to send in our Tx queue.
		 * If we have credits, it means that our Tx queue is blocked.
		 *
		 * Let's suppose the peer can't keep up with our Tx. He will
		 * flow control us by not sending us any credits, and we
		 * will stop Tx and start accumulating credits here.
		 * Up to the point where the peer will stop its Tx queue,
		 * for lack of credits.
		 * Let's assume the peer application is single threaded.
		 * It will block on Tx and never consume any Rx buffer.
		 * Deadlock. Guaranteed. - Jean II
		 */
	}

	/* Reset lock */
	self->rx_queue_lock = 0;
}

#ifdef CONFIG_PROC_FS
struct irttp_iter_state {
	int id;
};

static void *irttp_seq_start(struct seq_file *seq, loff_t *pos)
{
	struct irttp_iter_state *iter = seq->private;
	struct tsap_cb *self;

	/* Protect our access to the tsap list */
	spin_lock_irq(&irttp->tsaps->hb_spinlock);
	iter->id = 0;

	for (self = (struct tsap_cb *) hashbin_get_first(irttp->tsaps);
	     self != NULL;
	     self = (struct tsap_cb *) hashbin_get_next(irttp->tsaps)) {
		if (iter->id == *pos)
			break;
		++iter->id;
	}

	return self;
}

static void *irttp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct irttp_iter_state *iter = seq->private;

	++*pos;
	++iter->id;
	return (void *) hashbin_get_next(irttp->tsaps);
}

static void irttp_seq_stop(struct seq_file *seq, void *v)
{
	spin_unlock_irq(&irttp->tsaps->hb_spinlock);
}

static int irttp_seq_show(struct seq_file *seq, void *v)
{
	const struct irttp_iter_state *iter = seq->private;
	const struct tsap_cb *self = v;

	seq_printf(seq, "TSAP %d, ", iter->id);
	seq_printf(seq, "stsap_sel: %02x, ",
		   self->stsap_sel);
	seq_printf(seq, "dtsap_sel: %02x\n",
		   self->dtsap_sel);
	seq_printf(seq, "  connected: %s, ",
		   self->connected ? "TRUE" : "FALSE");
	seq_printf(seq, "avail credit: %d, ",
		   self->avail_credit);
	seq_printf(seq, "remote credit: %d, ",
		   self->remote_credit);
	seq_printf(seq, "send credit: %d\n",
		   self->send_credit);
	seq_printf(seq, "  tx packets: %lu, ",
		   self->stats.tx_packets);
	seq_printf(seq, "rx packets: %lu, ",
		   self->stats.rx_packets);
	seq_printf(seq, "tx_queue len: %u ",
		   skb_queue_len(&self->tx_queue));
	seq_printf(seq, "rx_queue len: %u\n",
		   skb_queue_len(&self->rx_queue));
	seq_printf(seq, "  tx_sdu_busy: %s, ",
		   self->tx_sdu_busy ? "TRUE" : "FALSE");
	seq_printf(seq, "rx_sdu_busy: %s\n",
		   self->rx_sdu_busy ? "TRUE" : "FALSE");
	seq_printf(seq, "  max_seg_size: %u, ",
		   self->max_seg_size);
	seq_printf(seq, "tx_max_sdu_size: %u, ",
		   self->tx_max_sdu_size);
	seq_printf(seq, "rx_max_sdu_size: %u\n",
		   self->rx_max_sdu_size);

	seq_printf(seq, "  Used by (%s)\n\n",
		   self->notify.name);
	return 0;
}

static const struct seq_operations irttp_seq_ops = {
	.start  = irttp_seq_start,
	.next   = irttp_seq_next,
	.stop   = irttp_seq_stop,
	.show   = irttp_seq_show,
};

static int irttp_seq_open(struct inode *inode, struct file *file)
{
	return seq_open_private(file, &irttp_seq_ops,
			sizeof(struct irttp_iter_state));
}

const struct file_operations irttp_seq_fops = {
	.owner		= THIS_MODULE,
	.open           = irttp_seq_open,
	.read           = seq_read,
	.llseek         = seq_lseek,
	.release	= seq_release_private,
};

#endif /* PROC_FS */
