/* $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/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/devfs_fs_kernel.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;
	um_idi_proc_entry->owner = THIS_MODULE;

	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 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)
{
	devfs_remove(DEVNAME);
	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);
	}
	devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);

	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)
{
	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);
	}
}
