
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/isdn/capilli.h>

#define DBG(format, arg...) do { \
printk(KERN_DEBUG "%s: " format "\n" , __FUNCTION__ , ## arg); \
} while (0)

struct capilib_msgidqueue {
	struct capilib_msgidqueue *next;
	u16 msgid;
};

struct capilib_ncci {
	struct list_head list;
	u16 applid;
	u32 ncci;
	u32 winsize;
	int   nmsg;
	struct capilib_msgidqueue *msgidqueue;
	struct capilib_msgidqueue *msgidlast;
	struct capilib_msgidqueue *msgidfree;
	struct capilib_msgidqueue msgidpool[CAPI_MAXDATAWINDOW];
};

// ---------------------------------------------------------------------------
// NCCI Handling

static inline void mq_init(struct capilib_ncci * np)
{
	u_int i;
	np->msgidqueue = NULL;
	np->msgidlast = NULL;
	np->nmsg = 0;
	memset(np->msgidpool, 0, sizeof(np->msgidpool));
	np->msgidfree = &np->msgidpool[0];
	for (i = 1; i < np->winsize; i++) {
		np->msgidpool[i].next = np->msgidfree;
		np->msgidfree = &np->msgidpool[i];
	}
}

static inline int mq_enqueue(struct capilib_ncci * np, u16 msgid)
{
	struct capilib_msgidqueue *mq;
	if ((mq = np->msgidfree) == 0)
		return 0;
	np->msgidfree = mq->next;
	mq->msgid = msgid;
	mq->next = NULL;
	if (np->msgidlast)
		np->msgidlast->next = mq;
	np->msgidlast = mq;
	if (!np->msgidqueue)
		np->msgidqueue = mq;
	np->nmsg++;
	return 1;
}

static inline int mq_dequeue(struct capilib_ncci * np, u16 msgid)
{
	struct capilib_msgidqueue **pp;
	for (pp = &np->msgidqueue; *pp; pp = &(*pp)->next) {
		if ((*pp)->msgid == msgid) {
			struct capilib_msgidqueue *mq = *pp;
			*pp = mq->next;
			if (mq == np->msgidlast)
				np->msgidlast = NULL;
			mq->next = np->msgidfree;
			np->msgidfree = mq;
			np->nmsg--;
			return 1;
		}
	}
	return 0;
}

void capilib_new_ncci(struct list_head *head, u16 applid, u32 ncci, u32 winsize)
{
	struct capilib_ncci *np;

	np = kmalloc(sizeof(*np), GFP_ATOMIC);
	if (!np) {
		printk(KERN_WARNING "capilib_new_ncci: no memory.\n");
		return;
	}
	if (winsize > CAPI_MAXDATAWINDOW) {
		printk(KERN_ERR "capi_new_ncci: winsize %d too big\n",
		       winsize);
		winsize = CAPI_MAXDATAWINDOW;
	}
	np->applid = applid;
	np->ncci = ncci;
	np->winsize = winsize;
	mq_init(np);
	list_add_tail(&np->list, head);
	DBG("kcapi: appl %d ncci 0x%x up", applid, ncci);
}

EXPORT_SYMBOL(capilib_new_ncci);

void capilib_free_ncci(struct list_head *head, u16 applid, u32 ncci)
{
	struct list_head *l;
	struct capilib_ncci *np;

	list_for_each(l, head) {
		np = list_entry(l, struct capilib_ncci, list);
		if (np->applid != applid)
			continue;
		if (np->ncci != ncci)
			continue;
		printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", applid, ncci);
		list_del(&np->list);
		kfree(np);
		return;
	}
	printk(KERN_ERR "capilib_free_ncci: ncci 0x%x not found\n", ncci);
}

EXPORT_SYMBOL(capilib_free_ncci);

void capilib_release_appl(struct list_head *head, u16 applid)
{
	struct list_head *l, *n;
	struct capilib_ncci *np;

	list_for_each_safe(l, n, head) {
		np = list_entry(l, struct capilib_ncci, list);
		if (np->applid != applid)
			continue;
		printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down\n", applid, np->ncci);
		list_del(&np->list);
		kfree(np);
	}
}

EXPORT_SYMBOL(capilib_release_appl);

void capilib_release(struct list_head *head)
{
	struct list_head *l, *n;
	struct capilib_ncci *np;

	list_for_each_safe(l, n, head) {
		np = list_entry(l, struct capilib_ncci, list);
		printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down\n", np->applid, np->ncci);
		list_del(&np->list);
		kfree(np);
	}
}

EXPORT_SYMBOL(capilib_release);

u16 capilib_data_b3_req(struct list_head *head, u16 applid, u32 ncci, u16 msgid)
{
	struct list_head *l;
	struct capilib_ncci *np;

	list_for_each(l, head) {
		np = list_entry(l, struct capilib_ncci, list);
		if (np->applid != applid)
			continue;
		if (np->ncci != ncci)
			continue;
		
		if (mq_enqueue(np, msgid) == 0)
			return CAPI_SENDQUEUEFULL;

		return CAPI_NOERROR;
	}
	printk(KERN_ERR "capilib_data_b3_req: ncci 0x%x not found\n", ncci);
	return CAPI_NOERROR;
}

EXPORT_SYMBOL(capilib_data_b3_req);

void capilib_data_b3_conf(struct list_head *head, u16 applid, u32 ncci, u16 msgid)
{
	struct list_head *l;
	struct capilib_ncci *np;

	list_for_each(l, head) {
		np = list_entry(l, struct capilib_ncci, list);
		if (np->applid != applid)
			continue;
		if (np->ncci != ncci)
			continue;
		
		if (mq_dequeue(np, msgid) == 0) {
			printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n",
			       msgid, ncci);
		}
		return;
	}
	printk(KERN_ERR "capilib_data_b3_conf: ncci 0x%x not found\n", ncci);
}

EXPORT_SYMBOL(capilib_data_b3_conf);
