/* 
 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
 * Licensed under the GPL
 * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
 *	Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
 */

#include "linux/config.h"
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/smp.h"
#include "linux/kernel_stat.h"
#include "linux/interrupt.h"
#include "linux/random.h"
#include "linux/slab.h"
#include "linux/file.h"
#include "linux/proc_fs.h"
#include "linux/init.h"
#include "linux/seq_file.h"
#include "linux/profile.h"
#include "linux/hardirq.h"
#include "asm/irq.h"
#include "asm/hw_irq.h"
#include "asm/atomic.h"
#include "asm/signal.h"
#include "asm/system.h"
#include "asm/errno.h"
#include "asm/uaccess.h"
#include "user_util.h"
#include "kern_util.h"
#include "irq_user.h"
#include "irq_kern.h"
#include "os.h"
#include "sigio.h"
#include "misc_constants.h"

/*
 * Generic, controller-independent functions:
 */

int show_interrupts(struct seq_file *p, void *v)
{
	int i = *(loff_t *) v, j;
	struct irqaction * action;
	unsigned long flags;

	if (i == 0) {
		seq_printf(p, "           ");
		for_each_online_cpu(j)
			seq_printf(p, "CPU%d       ",j);
		seq_putc(p, '\n');
	}

	if (i < NR_IRQS) {
		spin_lock_irqsave(&irq_desc[i].lock, flags);
		action = irq_desc[i].action;
		if (!action) 
			goto skip;
		seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP
		seq_printf(p, "%10u ", kstat_irqs(i));
#else
		for_each_online_cpu(j)
			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
		seq_printf(p, " %14s", irq_desc[i].handler->typename);
		seq_printf(p, "  %s", action->name);

		for (action=action->next; action; action = action->next)
			seq_printf(p, ", %s", action->name);

		seq_putc(p, '\n');
skip:
		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
	} else if (i == NR_IRQS) {
		seq_putc(p, '\n');
	}

	return 0;
}

struct irq_fd *active_fds = NULL;
static struct irq_fd **last_irq_ptr = &active_fds;

extern void free_irqs(void);

void sigio_handler(int sig, union uml_pt_regs *regs)
{
	struct irq_fd *irq_fd;
	int n;

	if(smp_sigio_handler()) return;
	while(1){
		n = os_waiting_for_events(active_fds);
		if (n <= 0) {
			if(n == -EINTR) continue;
			else break;
		}

		for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
			if(irq_fd->current_events != 0){
				irq_fd->current_events = 0;
				do_IRQ(irq_fd->irq, regs);
			}
		}
	}

	free_irqs();
}

static void maybe_sigio_broken(int fd, int type)
{
	if(os_isatty(fd)){
		if((type == IRQ_WRITE) && !pty_output_sigio){
			write_sigio_workaround();
			add_sigio_fd(fd, 0);
		}
		else if((type == IRQ_READ) && !pty_close_sigio){
			write_sigio_workaround();
			add_sigio_fd(fd, 1);
		}
	}
}


int activate_fd(int irq, int fd, int type, void *dev_id)
{
	struct pollfd *tmp_pfd;
	struct irq_fd *new_fd, *irq_fd;
	unsigned long flags;
	int pid, events, err, n;

	pid = os_getpid();
	err = os_set_fd_async(fd, pid);
	if(err < 0)
		goto out;

	new_fd = um_kmalloc(sizeof(*new_fd));
	err = -ENOMEM;
	if(new_fd == NULL)
		goto out;

	if(type == IRQ_READ) events = UM_POLLIN | UM_POLLPRI;
	else events = UM_POLLOUT;
	*new_fd = ((struct irq_fd) { .next  		= NULL,
				     .id 		= dev_id,
				     .fd 		= fd,
				     .type 		= type,
				     .irq 		= irq,
				     .pid  		= pid,
				     .events 		= events,
				     .current_events 	= 0 } );

	/* Critical section - locked by a spinlock because this stuff can
	 * be changed from interrupt handlers.  The stuff above is done
	 * outside the lock because it allocates memory.
	 */

	/* Actually, it only looks like it can be called from interrupt
	 * context.  The culprit is reactivate_fd, which calls
	 * maybe_sigio_broken, which calls write_sigio_workaround,
	 * which calls activate_fd.  However, write_sigio_workaround should
	 * only be called once, at boot time.  That would make it clear that
	 * this is called only from process context, and can be locked with
	 * a semaphore.
	 */
	flags = irq_lock();
	for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
		if((irq_fd->fd == fd) && (irq_fd->type == type)){
			printk("Registering fd %d twice\n", fd);
			printk("Irqs : %d, %d\n", irq_fd->irq, irq);
			printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id);
			goto out_unlock;
		}
	}

	/*-------------*/
	if(type == IRQ_WRITE)
		fd = -1;

	tmp_pfd = NULL;
	n = 0;

	while(1){
		n = os_create_pollfd(fd, events, tmp_pfd, n);
		if (n == 0)
			break;

		/* n > 0
		 * It means we couldn't put new pollfd to current pollfds
		 * and tmp_fds is NULL or too small for new pollfds array.
		 * Needed size is equal to n as minimum.
		 *
		 * Here we have to drop the lock in order to call
		 * kmalloc, which might sleep.
		 * If something else came in and changed the pollfds array
		 * so we will not be able to put new pollfd struct to pollfds
		 * then we free the buffer tmp_fds and try again.
		 */
		irq_unlock(flags);
		if (tmp_pfd != NULL) {
			kfree(tmp_pfd);
			tmp_pfd = NULL;
		}

		tmp_pfd = um_kmalloc(n);
		if (tmp_pfd == NULL)
			goto out_kfree;

		flags = irq_lock();
	}
	/*-------------*/

	*last_irq_ptr = new_fd;
	last_irq_ptr = &new_fd->next;

	irq_unlock(flags);

	/* This calls activate_fd, so it has to be outside the critical
	 * section.
	 */
	maybe_sigio_broken(fd, type);

	return(0);

 out_unlock:
	irq_unlock(flags);
 out_kfree:
	kfree(new_fd);
 out:
	return(err);
}

static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
{
	unsigned long flags;

	flags = irq_lock();
	os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr);
	irq_unlock(flags);
}

struct irq_and_dev {
	int irq;
	void *dev;
};

static int same_irq_and_dev(struct irq_fd *irq, void *d)
{
	struct irq_and_dev *data = d;

	return((irq->irq == data->irq) && (irq->id == data->dev));
}

void free_irq_by_irq_and_dev(unsigned int irq, void *dev)
{
	struct irq_and_dev data = ((struct irq_and_dev) { .irq  = irq,
							  .dev  = dev });

	free_irq_by_cb(same_irq_and_dev, &data);
}

static int same_fd(struct irq_fd *irq, void *fd)
{
	return(irq->fd == *((int *) fd));
}

void free_irq_by_fd(int fd)
{
	free_irq_by_cb(same_fd, &fd);
}

static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
{
	struct irq_fd *irq;
	int i = 0;
	int fdi;

	for(irq=active_fds; irq != NULL; irq = irq->next){
		if((irq->fd == fd) && (irq->irq == irqnum)) break;
		i++;
	}
	if(irq == NULL){
		printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
		goto out;
	}
	fdi = os_get_pollfd(i);
	if((fdi != -1) && (fdi != fd)){
		printk("find_irq_by_fd - mismatch between active_fds and "
		       "pollfds, fd %d vs %d, need %d\n", irq->fd,
		       fdi, fd);
		irq = NULL;
		goto out;
	}
	*index_out = i;
 out:
	return(irq);
}

void reactivate_fd(int fd, int irqnum)
{
	struct irq_fd *irq;
	unsigned long flags;
	int i;

	flags = irq_lock();
	irq = find_irq_by_fd(fd, irqnum, &i);
	if(irq == NULL){
		irq_unlock(flags);
		return;
	}
	os_set_pollfd(i, irq->fd);
	irq_unlock(flags);

	/* This calls activate_fd, so it has to be outside the critical
	 * section.
	 */
	maybe_sigio_broken(fd, irq->type);
}

void deactivate_fd(int fd, int irqnum)
{
	struct irq_fd *irq;
	unsigned long flags;
	int i;

	flags = irq_lock();
	irq = find_irq_by_fd(fd, irqnum, &i);
	if(irq == NULL)
		goto out;
	os_set_pollfd(i, -1);
 out:
	irq_unlock(flags);
}

int deactivate_all_fds(void)
{
	struct irq_fd *irq;
	int err;

	for(irq=active_fds;irq != NULL;irq = irq->next){
		err = os_clear_fd_async(irq->fd);
		if(err)
			return(err);
	}
	/* If there is a signal already queued, after unblocking ignore it */
	os_set_ioignore();

	return(0);
}

void forward_interrupts(int pid)
{
	struct irq_fd *irq;
	unsigned long flags;
	int err;

	flags = irq_lock();
	for(irq=active_fds;irq != NULL;irq = irq->next){
		err = os_set_owner(irq->fd, pid);
		if(err < 0){
			/* XXX Just remove the irq rather than
			 * print out an infinite stream of these
			 */
			printk("Failed to forward %d to pid %d, err = %d\n",
			       irq->fd, pid, -err);
		}

		irq->pid = pid;
	}
	irq_unlock(flags);
}

/*
 * do_IRQ handles all normal device IRQ's (the special
 * SMP cross-CPU interrupts have their own specific
 * handlers).
 */
unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
{
       irq_enter();
       __do_IRQ(irq, (struct pt_regs *) regs);
       irq_exit();
       return 1;
}

int um_request_irq(unsigned int irq, int fd, int type,
		   irqreturn_t (*handler)(int, void *, struct pt_regs *),
		   unsigned long irqflags, const char * devname,
		   void *dev_id)
{
	int err;

	err = request_irq(irq, handler, irqflags, devname, dev_id);
	if(err)
		return(err);

	if(fd != -1)
		err = activate_fd(irq, fd, type, dev_id);
	return(err);
}
EXPORT_SYMBOL(um_request_irq);
EXPORT_SYMBOL(reactivate_fd);

static DEFINE_SPINLOCK(irq_spinlock);

unsigned long irq_lock(void)
{
	unsigned long flags;

	spin_lock_irqsave(&irq_spinlock, flags);
	return(flags);
}

void irq_unlock(unsigned long flags)
{
	spin_unlock_irqrestore(&irq_spinlock, flags);
}

/* hw_interrupt_type must define (startup || enable) &&
 * (shutdown || disable) && end */
static void dummy(unsigned int irq)
{
}

/* This is used for everything else than the timer. */
static struct hw_interrupt_type normal_irq_type = {
	.typename = "SIGIO",
	.release = free_irq_by_irq_and_dev,
	.disable = dummy,
	.enable = dummy,
	.ack = dummy,
	.end = dummy
};

static struct hw_interrupt_type SIGVTALRM_irq_type = {
	.typename = "SIGVTALRM",
	.release = free_irq_by_irq_and_dev,
	.shutdown = dummy, /* never called */
	.disable = dummy,
	.enable = dummy,
	.ack = dummy,
	.end = dummy
};

void __init init_IRQ(void)
{
	int i;

	irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
	irq_desc[TIMER_IRQ].action = NULL;
	irq_desc[TIMER_IRQ].depth = 1;
	irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
	enable_irq(TIMER_IRQ);
	for(i=1;i<NR_IRQS;i++){
		irq_desc[i].status = IRQ_DISABLED;
		irq_desc[i].action = NULL;
		irq_desc[i].depth = 1;
		irq_desc[i].handler = &normal_irq_type;
		enable_irq(i);
	}
}

int init_aio_irq(int irq, char *name, irqreturn_t (*handler)(int, void *,
							     struct pt_regs *))
{
	int fds[2], err;

	err = os_pipe(fds, 1, 1);
	if(err){
		printk("init_aio_irq - os_pipe failed, err = %d\n", -err);
		goto out;
	}

	err = um_request_irq(irq, fds[0], IRQ_READ, handler,
			     SA_INTERRUPT | SA_SAMPLE_RANDOM, name,
			     (void *) (long) fds[0]);
	if(err){
		printk("init_aio_irq - : um_request_irq failed, err = %d\n",
		       err);
		goto out_close;
	}

	err = fds[1];
	goto out;

 out_close:
	os_close_file(fds[0]);
	os_close_file(fds[1]);
 out:
	return(err);
}
