/*
 * SN Platform system controller communication support
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2004, 2006 Silicon Graphics, Inc. All rights reserved.
 */

/*
 * System controller communication driver
 *
 * This driver allows a user process to communicate with the system
 * controller (a.k.a. "IRouter") network in an SGI SN system.
 */

#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/module.h>
#include <asm/sn/geo.h>
#include <asm/sn/nodepda.h>
#include "snsc.h"

#define SYSCTL_BASENAME	"snsc"

#define SCDRV_BUFSZ	2048
#define SCDRV_TIMEOUT	1000

static DEFINE_MUTEX(scdrv_mutex);
static irqreturn_t
scdrv_interrupt(int irq, void *subch_data)
{
	struct subch_data_s *sd = subch_data;
	unsigned long flags;
	int status;

	spin_lock_irqsave(&sd->sd_rlock, flags);
	spin_lock(&sd->sd_wlock);
	status = ia64_sn_irtr_intr(sd->sd_nasid, sd->sd_subch);

	if (status > 0) {
		if (status & SAL_IROUTER_INTR_RECV) {
			wake_up(&sd->sd_rq);
		}
		if (status & SAL_IROUTER_INTR_XMIT) {
			ia64_sn_irtr_intr_disable
			    (sd->sd_nasid, sd->sd_subch,
			     SAL_IROUTER_INTR_XMIT);
			wake_up(&sd->sd_wq);
		}
	}
	spin_unlock(&sd->sd_wlock);
	spin_unlock_irqrestore(&sd->sd_rlock, flags);
	return IRQ_HANDLED;
}

/*
 * scdrv_open
 *
 * Reserve a subchannel for system controller communication.
 */

static int
scdrv_open(struct inode *inode, struct file *file)
{
	struct sysctl_data_s *scd;
	struct subch_data_s *sd;
	int rv;

	/* look up device info for this device file */
	scd = container_of(inode->i_cdev, struct sysctl_data_s, scd_cdev);

	/* allocate memory for subchannel data */
	sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL);
	if (sd == NULL) {
		printk("%s: couldn't allocate subchannel data\n",
		       __func__);
		return -ENOMEM;
	}

	/* initialize subch_data_s fields */
	sd->sd_nasid = scd->scd_nasid;
	sd->sd_subch = ia64_sn_irtr_open(scd->scd_nasid);

	if (sd->sd_subch < 0) {
		kfree(sd);
		printk("%s: couldn't allocate subchannel\n", __func__);
		return -EBUSY;
	}

	spin_lock_init(&sd->sd_rlock);
	spin_lock_init(&sd->sd_wlock);
	init_waitqueue_head(&sd->sd_rq);
	init_waitqueue_head(&sd->sd_wq);
	sema_init(&sd->sd_rbs, 1);
	sema_init(&sd->sd_wbs, 1);

	file->private_data = sd;

	/* hook this subchannel up to the system controller interrupt */
	mutex_lock(&scdrv_mutex);
	rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt,
			 IRQF_SHARED, SYSCTL_BASENAME, sd);
	if (rv) {
		ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
		kfree(sd);
		printk("%s: irq request failed (%d)\n", __func__, rv);
		mutex_unlock(&scdrv_mutex);
		return -EBUSY;
	}
	mutex_unlock(&scdrv_mutex);
	return 0;
}

/*
 * scdrv_release
 *
 * Release a previously-reserved subchannel.
 */

static int
scdrv_release(struct inode *inode, struct file *file)
{
	struct subch_data_s *sd = (struct subch_data_s *) file->private_data;
	int rv;

	/* free the interrupt */
	free_irq(SGI_UART_VECTOR, sd);

	/* ask SAL to close the subchannel */
	rv = ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);

	kfree(sd);
	return rv;
}

/*
 * scdrv_read
 *
 * Called to read bytes from the open IRouter pipe.
 *
 */

static inline int
read_status_check(struct subch_data_s *sd, int *len)
{
	return ia64_sn_irtr_recv(sd->sd_nasid, sd->sd_subch, sd->sd_rb, len);
}

static ssize_t
scdrv_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)
{
	int status;
	int len;
	unsigned long flags;
	struct subch_data_s *sd = (struct subch_data_s *) file->private_data;

	/* try to get control of the read buffer */
	if (down_trylock(&sd->sd_rbs)) {
		/* somebody else has it now;
		 * if we're non-blocking, then exit...
		 */
		if (file->f_flags & O_NONBLOCK) {
			return -EAGAIN;
		}
		/* ...or if we want to block, then do so here */
		if (down_interruptible(&sd->sd_rbs)) {
			/* something went wrong with wait */
			return -ERESTARTSYS;
		}
	}

	/* anything to read? */
	len = CHUNKSIZE;
	spin_lock_irqsave(&sd->sd_rlock, flags);
	status = read_status_check(sd, &len);

	/* if not, and we're blocking I/O, loop */
	while (status < 0) {
		DECLARE_WAITQUEUE(wait, current);

		if (file->f_flags & O_NONBLOCK) {
			spin_unlock_irqrestore(&sd->sd_rlock, flags);
			up(&sd->sd_rbs);
			return -EAGAIN;
		}

		len = CHUNKSIZE;
		set_current_state(TASK_INTERRUPTIBLE);
		add_wait_queue(&sd->sd_rq, &wait);
		spin_unlock_irqrestore(&sd->sd_rlock, flags);

		schedule_timeout(SCDRV_TIMEOUT);

		remove_wait_queue(&sd->sd_rq, &wait);
		if (signal_pending(current)) {
			/* wait was interrupted */
			up(&sd->sd_rbs);
			return -ERESTARTSYS;
		}

		spin_lock_irqsave(&sd->sd_rlock, flags);
		status = read_status_check(sd, &len);
	}
	spin_unlock_irqrestore(&sd->sd_rlock, flags);

	if (len > 0) {
		/* we read something in the last read_status_check(); copy
		 * it out to user space
		 */
		if (count < len) {
			pr_debug("%s: only accepting %d of %d bytes\n",
				 __func__, (int) count, len);
		}
		len = min((int) count, len);
		if (copy_to_user(buf, sd->sd_rb, len))
			len = -EFAULT;
	}

	/* release the read buffer and wake anyone who might be
	 * waiting for it
	 */
	up(&sd->sd_rbs);

	/* return the number of characters read in */
	return len;
}

/*
 * scdrv_write
 *
 * Writes a chunk of an IRouter packet (or other system controller data)
 * to the system controller.
 *
 */
static inline int
write_status_check(struct subch_data_s *sd, int count)
{
	return ia64_sn_irtr_send(sd->sd_nasid, sd->sd_subch, sd->sd_wb, count);
}

static ssize_t
scdrv_write(struct file *file, const char __user *buf,
	    size_t count, loff_t *f_pos)
{
	unsigned long flags;
	int status;
	struct subch_data_s *sd = (struct subch_data_s *) file->private_data;

	/* try to get control of the write buffer */
	if (down_trylock(&sd->sd_wbs)) {
		/* somebody else has it now;
		 * if we're non-blocking, then exit...
		 */
		if (file->f_flags & O_NONBLOCK) {
			return -EAGAIN;
		}
		/* ...or if we want to block, then do so here */
		if (down_interruptible(&sd->sd_wbs)) {
			/* something went wrong with wait */
			return -ERESTARTSYS;
		}
	}

	count = min((int) count, CHUNKSIZE);
	if (copy_from_user(sd->sd_wb, buf, count)) {
		up(&sd->sd_wbs);
		return -EFAULT;
	}

	/* try to send the buffer */
	spin_lock_irqsave(&sd->sd_wlock, flags);
	status = write_status_check(sd, count);

	/* if we failed, and we want to block, then loop */
	while (status <= 0) {
		DECLARE_WAITQUEUE(wait, current);

		if (file->f_flags & O_NONBLOCK) {
			spin_unlock(&sd->sd_wlock);
			up(&sd->sd_wbs);
			return -EAGAIN;
		}

		set_current_state(TASK_INTERRUPTIBLE);
		add_wait_queue(&sd->sd_wq, &wait);
		spin_unlock_irqrestore(&sd->sd_wlock, flags);

		schedule_timeout(SCDRV_TIMEOUT);

		remove_wait_queue(&sd->sd_wq, &wait);
		if (signal_pending(current)) {
			/* wait was interrupted */
			up(&sd->sd_wbs);
			return -ERESTARTSYS;
		}

		spin_lock_irqsave(&sd->sd_wlock, flags);
		status = write_status_check(sd, count);
	}
	spin_unlock_irqrestore(&sd->sd_wlock, flags);

	/* release the write buffer and wake anyone who's waiting for it */
	up(&sd->sd_wbs);

	/* return the number of characters accepted (should be the complete
	 * "chunk" as requested)
	 */
	if ((status >= 0) && (status < count)) {
		pr_debug("Didn't accept the full chunk; %d of %d\n",
			 status, (int) count);
	}
	return status;
}

static unsigned int
scdrv_poll(struct file *file, struct poll_table_struct *wait)
{
	unsigned int mask = 0;
	int status = 0;
	struct subch_data_s *sd = (struct subch_data_s *) file->private_data;
	unsigned long flags;

	poll_wait(file, &sd->sd_rq, wait);
	poll_wait(file, &sd->sd_wq, wait);

	spin_lock_irqsave(&sd->sd_rlock, flags);
	spin_lock(&sd->sd_wlock);
	status = ia64_sn_irtr_intr(sd->sd_nasid, sd->sd_subch);
	spin_unlock(&sd->sd_wlock);
	spin_unlock_irqrestore(&sd->sd_rlock, flags);

	if (status > 0) {
		if (status & SAL_IROUTER_INTR_RECV) {
			mask |= POLLIN | POLLRDNORM;
		}
		if (status & SAL_IROUTER_INTR_XMIT) {
			mask |= POLLOUT | POLLWRNORM;
		}
	}

	return mask;
}

static const struct file_operations scdrv_fops = {
	.owner =	THIS_MODULE,
	.read =		scdrv_read,
	.write =	scdrv_write,
	.poll =		scdrv_poll,
	.open =		scdrv_open,
	.release =	scdrv_release,
	.llseek =	noop_llseek,
};

static struct class *snsc_class;

/*
 * scdrv_init
 *
 * Called at boot time to initialize the system controller communication
 * facility.
 */
int __init
scdrv_init(void)
{
	geoid_t geoid;
	cnodeid_t cnode;
	char devname[32];
	char *devnamep;
	struct sysctl_data_s *scd;
	void *salbuf;
	dev_t first_dev, dev;
	nasid_t event_nasid;

	if (!ia64_platform_is("sn2"))
		return -ENODEV;

	event_nasid = ia64_sn_get_console_nasid();

	if (alloc_chrdev_region(&first_dev, 0, num_cnodes,
				SYSCTL_BASENAME) < 0) {
		printk("%s: failed to register SN system controller device\n",
		       __func__);
		return -ENODEV;
	}
	snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME);

	for (cnode = 0; cnode < num_cnodes; cnode++) {
			geoid = cnodeid_get_geoid(cnode);
			devnamep = devname;
			format_module_id(devnamep, geo_module(geoid),
					 MODULE_FORMAT_BRIEF);
			devnamep = devname + strlen(devname);
			sprintf(devnamep, "^%d#%d", geo_slot(geoid),
				geo_slab(geoid));

			/* allocate sysctl device data */
			scd = kzalloc(sizeof (struct sysctl_data_s),
				      GFP_KERNEL);
			if (!scd) {
				printk("%s: failed to allocate device info"
				       "for %s/%s\n", __func__,
				       SYSCTL_BASENAME, devname);
				continue;
			}

			/* initialize sysctl device data fields */
			scd->scd_nasid = cnodeid_to_nasid(cnode);
			if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) {
				printk("%s: failed to allocate driver buffer"
				       "(%s%s)\n", __func__,
				       SYSCTL_BASENAME, devname);
				kfree(scd);
				continue;
			}

			if (ia64_sn_irtr_init(scd->scd_nasid, salbuf,
					      SCDRV_BUFSZ) < 0) {
				printk
				    ("%s: failed to initialize SAL for"
				     " system controller communication"
				     " (%s/%s): outdated PROM?\n",
				     __func__, SYSCTL_BASENAME, devname);
				kfree(scd);
				kfree(salbuf);
				continue;
			}

			dev = first_dev + cnode;
			cdev_init(&scd->scd_cdev, &scdrv_fops);
			if (cdev_add(&scd->scd_cdev, dev, 1)) {
				printk("%s: failed to register system"
				       " controller device (%s%s)\n",
				       __func__, SYSCTL_BASENAME, devname);
				kfree(scd);
				kfree(salbuf);
				continue;
			}

			device_create(snsc_class, NULL, dev, NULL,
				      "%s", devname);

			ia64_sn_irtr_intr_enable(scd->scd_nasid,
						 0 /*ignored */ ,
						 SAL_IROUTER_INTR_RECV);

                        /* on the console nasid, prepare to receive
                         * system controller environmental events
                         */
                        if(scd->scd_nasid == event_nasid) {
                                scdrv_event_init(scd);
                        }
	}
	return 0;
}

module_init(scdrv_init);
