/* $Id: divasi.c,v 1.25.6.2 2005/01/31 12:22:20 armin Exp $
 *
 * Driver for Eicon DIVA Server ISDN cards.
 * User Mode IDI Interface 
 *
 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>

#include "platform.h"
#include "di_defs.h"
#include "divasync.h"
#include "um_xdi.h"
#include "um_idi.h"

static char *main_revision = "$Revision: 1.25.6.2 $";

static int major;

MODULE_DESCRIPTION("User IDI Interface for Eicon ISDN cards");
MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
MODULE_SUPPORTED_DEVICE("DIVA card driver");
MODULE_LICENSE("GPL");

typedef struct _diva_um_idi_os_context {
	wait_queue_head_t read_wait;
	wait_queue_head_t close_wait;
	struct timer_list diva_timer_id;
	int aborted;
	int adapter_nr;
} diva_um_idi_os_context_t;

static char *DRIVERNAME = "Eicon DIVA - User IDI (http://www.melware.net)";
static char *DRIVERLNAME = "diva_idi";
static char *DEVNAME = "DivasIDI";
char *DRIVERRELEASE_IDI = "2.0";

extern int idifunc_init(void);
extern void idifunc_finit(void);

/*
 *  helper functions
 */
static char *getrev(const char *revision)
{
	char *rev;
	char *p;
	if ((p = strchr(revision, ':'))) {
		rev = p + 2;
		p = strchr(rev, '$');
		*--p = 0;
	} else
		rev = "1.0";
	return rev;
}

/*
 *  LOCALS
 */
static ssize_t um_idi_read(struct file *file, char __user *buf, size_t count,
			   loff_t * offset);
static ssize_t um_idi_write(struct file *file, const char __user *buf,
			    size_t count, loff_t * offset);
static unsigned int um_idi_poll(struct file *file, poll_table * wait);
static int um_idi_open(struct inode *inode, struct file *file);
static int um_idi_release(struct inode *inode, struct file *file);
static int remove_entity(void *entity);
static void diva_um_timer_function(unsigned long data);

/*
 * proc entry
 */
extern struct proc_dir_entry *proc_net_eicon;
static struct proc_dir_entry *um_idi_proc_entry = NULL;

static int
um_idi_proc_read(char *page, char **start, off_t off, int count, int *eof,
		 void *data)
{
	int len = 0;
	char tmprev[32];

	len += sprintf(page + len, "%s\n", DRIVERNAME);
	len += sprintf(page + len, "name     : %s\n", DRIVERLNAME);
	len += sprintf(page + len, "release  : %s\n", DRIVERRELEASE_IDI);
	strcpy(tmprev, main_revision);
	len += sprintf(page + len, "revision : %s\n", getrev(tmprev));
	len += sprintf(page + len, "build    : %s\n", DIVA_BUILD);
	len += sprintf(page + len, "major    : %d\n", major);

	if (off + count >= len)
		*eof = 1;
	if (len < off)
		return 0;
	*start = page + off;
	return ((count < len - off) ? count : len - off);
}

static int DIVA_INIT_FUNCTION create_um_idi_proc(void)
{
	um_idi_proc_entry = create_proc_entry(DRIVERLNAME,
					      S_IFREG | S_IRUGO | S_IWUSR,
					      proc_net_eicon);
	if (!um_idi_proc_entry)
		return (0);

	um_idi_proc_entry->read_proc = um_idi_proc_read;

	return (1);
}

static void remove_um_idi_proc(void)
{
	if (um_idi_proc_entry) {
		remove_proc_entry(DRIVERLNAME, proc_net_eicon);
		um_idi_proc_entry = NULL;
	}
}

static const struct file_operations divas_idi_fops = {
	.owner   = THIS_MODULE,
	.llseek  = no_llseek,
	.read    = um_idi_read,
	.write   = um_idi_write,
	.poll    = um_idi_poll,
	.open    = um_idi_open,
	.release = um_idi_release
};

static void divas_idi_unregister_chrdev(void)
{
	unregister_chrdev(major, DEVNAME);
}

static int DIVA_INIT_FUNCTION divas_idi_register_chrdev(void)
{
	if ((major = register_chrdev(0, DEVNAME, &divas_idi_fops)) < 0)
	{
		printk(KERN_ERR "%s: failed to create /dev entry.\n",
		       DRIVERLNAME);
		return (0);
	}

	return (1);
}

/*
** Driver Load
*/
static int DIVA_INIT_FUNCTION divasi_init(void)
{
	char tmprev[50];
	int ret = 0;

	printk(KERN_INFO "%s\n", DRIVERNAME);
	printk(KERN_INFO "%s: Rel:%s  Rev:", DRIVERLNAME, DRIVERRELEASE_IDI);
	strcpy(tmprev, main_revision);
	printk("%s  Build: %s\n", getrev(tmprev), DIVA_BUILD);

	if (!divas_idi_register_chrdev()) {
		ret = -EIO;
		goto out;
	}

	if (!create_um_idi_proc()) {
		divas_idi_unregister_chrdev();
		printk(KERN_ERR "%s: failed to create proc entry.\n",
		       DRIVERLNAME);
		ret = -EIO;
		goto out;
	}

	if (!(idifunc_init())) {
		remove_um_idi_proc();
		divas_idi_unregister_chrdev();
		printk(KERN_ERR "%s: failed to connect to DIDD.\n",
		       DRIVERLNAME);
		ret = -EIO;
		goto out;
	}
	printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);

      out:
	return (ret);
}


/*
** Driver Unload
*/
static void DIVA_EXIT_FUNCTION divasi_exit(void)
{
	idifunc_finit();
	remove_um_idi_proc();
	divas_idi_unregister_chrdev();

	printk(KERN_INFO "%s: module unloaded.\n", DRIVERLNAME);
}

module_init(divasi_init);
module_exit(divasi_exit);


/*
 *  FILE OPERATIONS
 */

static int
divas_um_idi_copy_to_user(void *os_handle, void *dst, const void *src,
			  int length)
{
	memcpy(dst, src, length);
	return (length);
}

static ssize_t
um_idi_read(struct file *file, char __user *buf, size_t count, loff_t * offset)
{
	diva_um_idi_os_context_t *p_os;
	int ret = -EINVAL;
	void *data;

	if (!file->private_data) {
		return (-ENODEV);
	}

	if (!
	    (p_os =
	     (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->
								    private_data)))
	{
		return (-ENODEV);
	}
	if (p_os->aborted) {
		return (-ENODEV);
	}

	if (!(data = diva_os_malloc(0, count))) {
		return (-ENOMEM);
	}

	ret = diva_um_idi_read(file->private_data,
			       file, data, count,
			       divas_um_idi_copy_to_user);
	switch (ret) {
	case 0:		/* no message available */
		ret = (-EAGAIN);
		break;
	case (-1):		/* adapter was removed */
		ret = (-ENODEV);
		break;
	case (-2):		/* message_length > length of user buffer */
		ret = (-EFAULT);
		break;
	}

	if (ret > 0) {
		if (copy_to_user(buf, data, ret)) {
			ret = (-EFAULT);
		}
	}

	diva_os_free(0, data);
	DBG_TRC(("read: ret %d", ret));
	return (ret);
}


static int
divas_um_idi_copy_from_user(void *os_handle, void *dst, const void *src,
			    int length)
{
	memcpy(dst, src, length);
	return (length);
}

static int um_idi_open_adapter(struct file *file, int adapter_nr)
{
	diva_um_idi_os_context_t *p_os;
	void *e =
	    divas_um_idi_create_entity((dword) adapter_nr, (void *) file);

	if (!(file->private_data = e)) {
		return (0);
	}
	p_os = (diva_um_idi_os_context_t *) diva_um_id_get_os_context(e);
	init_waitqueue_head(&p_os->read_wait);
	init_waitqueue_head(&p_os->close_wait);
	init_timer(&p_os->diva_timer_id);
	p_os->diva_timer_id.function = (void *) diva_um_timer_function;
	p_os->diva_timer_id.data = (unsigned long) p_os;
	p_os->aborted = 0;
	p_os->adapter_nr = adapter_nr;
	return (1);
}

static ssize_t
um_idi_write(struct file *file, const char __user *buf, size_t count,
	     loff_t * offset)
{
	diva_um_idi_os_context_t *p_os;
	int ret = -EINVAL;
	void *data;
	int adapter_nr = 0;

	if (!file->private_data) {
		/* the first write() selects the adapter_nr */
		if (count == sizeof(int)) {
			if (copy_from_user
			    ((void *) &adapter_nr, buf,
			     count)) return (-EFAULT);
			if (!(um_idi_open_adapter(file, adapter_nr)))
				return (-ENODEV);
			return (count);
		} else
			return (-ENODEV);
	}

	if (!(p_os =
	     (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->
								    private_data)))
	{
		return (-ENODEV);
	}
	if (p_os->aborted) {
		return (-ENODEV);
	}

	if (!(data = diva_os_malloc(0, count))) {
		return (-ENOMEM);
	}

	if (copy_from_user(data, buf, count)) {
		ret = -EFAULT;
	} else {
		ret = diva_um_idi_write(file->private_data,
					file, data, count,
					divas_um_idi_copy_from_user);
		switch (ret) {
		case 0:	/* no space available */
			ret = (-EAGAIN);
			break;
		case (-1):	/* adapter was removed */
			ret = (-ENODEV);
			break;
		case (-2):	/* length of user buffer > max message_length */
			ret = (-EFAULT);
			break;
		}
	}
	diva_os_free(0, data);
	DBG_TRC(("write: ret %d", ret));
	return (ret);
}

static unsigned int um_idi_poll(struct file *file, poll_table * wait)
{
	diva_um_idi_os_context_t *p_os;

	if (!file->private_data) {
		return (POLLERR);
	}

	if ((!(p_os =
	       (diva_um_idi_os_context_t *)
	       diva_um_id_get_os_context(file->private_data)))
	    || p_os->aborted) {
		return (POLLERR);
	}

	poll_wait(file, &p_os->read_wait, wait);

	if (p_os->aborted) {
		return (POLLERR);
	}

	switch (diva_user_mode_idi_ind_ready(file->private_data, file)) {
	case (-1):
		return (POLLERR);

	case 0:
		return (0);
	}

	return (POLLIN | POLLRDNORM);
}

static int um_idi_open(struct inode *inode, struct file *file)
{
	cycle_kernel_lock();
	return (0);
}


static int um_idi_release(struct inode *inode, struct file *file)
{
	diva_um_idi_os_context_t *p_os;
	unsigned int adapter_nr;
	int ret = 0;

	if (!(file->private_data)) {
		ret = -ENODEV;
		goto out;
	}

	if (!(p_os =
		(diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->private_data))) {
		ret = -ENODEV;
		goto out;
	}

	adapter_nr = p_os->adapter_nr;

	if ((ret = remove_entity(file->private_data))) {
		goto out;
	}

	if (divas_um_idi_delete_entity
	    ((int) adapter_nr, file->private_data)) {
		ret = -ENODEV;
		goto out;
	}

      out:
	return (ret);
}

int diva_os_get_context_size(void)
{
	return (sizeof(diva_um_idi_os_context_t));
}

void diva_os_wakeup_read(void *os_context)
{
	diva_um_idi_os_context_t *p_os =
	    (diva_um_idi_os_context_t *) os_context;
	wake_up_interruptible(&p_os->read_wait);
}

void diva_os_wakeup_close(void *os_context)
{
	diva_um_idi_os_context_t *p_os =
	    (diva_um_idi_os_context_t *) os_context;
	wake_up_interruptible(&p_os->close_wait);
}

static
void diva_um_timer_function(unsigned long data)
{
	diva_um_idi_os_context_t *p_os = (diva_um_idi_os_context_t *) data;

	p_os->aborted = 1;
	wake_up_interruptible(&p_os->read_wait);
	wake_up_interruptible(&p_os->close_wait);
	DBG_ERR(("entity removal watchdog"))
}

/*
**  If application exits without entity removal this function will remove
**  entity and block until removal is complete
*/
static int remove_entity(void *entity)
{
	struct task_struct *curtask = current;
	diva_um_idi_os_context_t *p_os;

	diva_um_idi_stop_wdog(entity);

	if (!entity) {
		DBG_FTL(("Zero entity on remove"))
		return (0);
	}

	if (!(p_os =
	     (diva_um_idi_os_context_t *)
	     diva_um_id_get_os_context(entity))) {
		DBG_FTL(("Zero entity os context on remove"))
		return (0);
	}

	if (!divas_um_idi_entity_assigned(entity) || p_os->aborted) {
		/*
		   Entity is not assigned, also can be removed
		 */
		return (0);
	}

	DBG_TRC(("E(%08x) check remove", entity))

	/*
	   If adapter not answers on remove request inside of
	   10 Sec, then adapter is dead
	 */
	diva_um_idi_start_wdog(entity);

	{
		DECLARE_WAITQUEUE(wait, curtask);

		add_wait_queue(&p_os->close_wait, &wait);
		for (;;) {
			set_current_state(TASK_INTERRUPTIBLE);
			if (!divas_um_idi_entity_start_remove(entity)
			    || p_os->aborted) {
				break;
			}
			schedule();
		}
		set_current_state(TASK_RUNNING);
		remove_wait_queue(&p_os->close_wait, &wait);
	}

	DBG_TRC(("E(%08x) start remove", entity))
	{
		DECLARE_WAITQUEUE(wait, curtask);

		add_wait_queue(&p_os->close_wait, &wait);
		for (;;) {
			set_current_state(TASK_INTERRUPTIBLE);
			if (!divas_um_idi_entity_assigned(entity)
			    || p_os->aborted) {
				break;
			}
			schedule();
		}
		set_current_state(TASK_RUNNING);
		remove_wait_queue(&p_os->close_wait, &wait);
	}

	DBG_TRC(("E(%08x) remove complete, aborted:%d", entity,
		 p_os->aborted))

	diva_um_idi_stop_wdog(entity);

	p_os->aborted = 0;

	return (0);
}

/*
 * timer watchdog
 */
void diva_um_idi_start_wdog(void *entity)
{
	diva_um_idi_os_context_t *p_os;

	if (entity &&
	    ((p_os =
	      (diva_um_idi_os_context_t *)
	      diva_um_id_get_os_context(entity)))) {
		mod_timer(&p_os->diva_timer_id, jiffies + 10 * HZ);
	}
}

void diva_um_idi_stop_wdog(void *entity)
{
	diva_um_idi_os_context_t *p_os;

	if (entity &&
	    ((p_os =
	      (diva_um_idi_os_context_t *)
	      diva_um_id_get_os_context(entity)))) {
		del_timer(&p_os->diva_timer_id);
	}
}
