/* -*- linux-c -*-
 *
 *  drivers/char/viocons.c
 *
 *  iSeries Virtual Terminal
 *
 *  Authors: Dave Boutcher <boutcher@us.ibm.com>
 *           Ryan Arnold <ryanarn@us.ibm.com>
 *           Colin Devilbiss <devilbis@us.ibm.com>
 *           Stephen Rothwell <sfr@au1.ibm.com>
 *
 * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation
 *
 * This program is free software;  you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) anyu later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/errno.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/spinlock.h>
#include <asm/ioctls.h>
#include <linux/kd.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/sysrq.h>

#include <asm/iseries/vio.h>
#include <asm/iseries/hv_lp_event.h>
#include <asm/iseries/hv_call_event.h>
#include <asm/iseries/hv_lp_config.h>
#include <asm/iseries/hv_call.h>

#ifdef CONFIG_VT
#error You must turn off CONFIG_VT to use CONFIG_VIOCONS
#endif

#define VIOTTY_MAGIC (0x0DCB)
#define VTTY_PORTS 10

#define VIOCONS_KERN_WARN	KERN_WARNING "viocons: "
#define VIOCONS_KERN_INFO	KERN_INFO "viocons: "

static DEFINE_SPINLOCK(consolelock);
static DEFINE_SPINLOCK(consoleloglock);

#ifdef CONFIG_MAGIC_SYSRQ
static int vio_sysrq_pressed;
extern int sysrq_enabled;
#endif

#define VIOCHAR_NUM_BUF		16

/*
 * Our port information.  We store a pointer to one entry in the
 * tty_driver_data
 */
static struct port_info {
	int magic;
	struct tty_struct *tty;
	HvLpIndex lp;
	u8 vcons;
	u64 seq;	/* sequence number of last HV send */
	u64 ack;	/* last ack from HV */
/*
 * When we get writes faster than we can send it to the partition,
 * buffer the data here. Note that used is a bit map of used buffers.
 * It had better have enough bits to hold VIOCHAR_NUM_BUF the bitops assume
 * it is a multiple of unsigned long
 */
	unsigned long used;
	u8 *buffer[VIOCHAR_NUM_BUF];
	int bufferBytes[VIOCHAR_NUM_BUF];
	int curbuf;
	int bufferOverflow;
	int overflowMessage;
} port_info[VTTY_PORTS];

#define viochar_is_console(pi)	((pi) == &port_info[0])
#define viochar_port(pi)	((pi) - &port_info[0])

static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp);

static struct tty_driver *viotty_driver;

static void hvlog(char *fmt, ...)
{
	int i;
	unsigned long flags;
	va_list args;
	static char buf[256];

	spin_lock_irqsave(&consoleloglock, flags);
	va_start(args, fmt);
	i = vscnprintf(buf, sizeof(buf) - 1, fmt, args);
	va_end(args);
	buf[i++] = '\r';
	HvCall_writeLogBuffer(buf, i);
	spin_unlock_irqrestore(&consoleloglock, flags);
}

static void hvlogOutput(const char *buf, int count)
{
	unsigned long flags;
	int begin;
	int index;
	static const char cr = '\r';

	begin = 0;
	spin_lock_irqsave(&consoleloglock, flags);
	for (index = 0; index < count; index++) {
		if (buf[index] == '\n') {
			/*
			 * Start right after the last '\n' or at the zeroth
			 * array position and output the number of characters
			 * including the newline.
			 */
			HvCall_writeLogBuffer(&buf[begin], index - begin + 1);
			begin = index + 1;
			HvCall_writeLogBuffer(&cr, 1);
		}
	}
	if ((index - begin) > 0)
		HvCall_writeLogBuffer(&buf[begin], index - begin);
	spin_unlock_irqrestore(&consoleloglock, flags);
}

/*
 * Make sure we're pointing to a valid port_info structure.  Shamelessly
 * plagerized from serial.c
 */
static inline int viotty_paranoia_check(struct port_info *pi,
					char *name, const char *routine)
{
	static const char *bad_pi_addr = VIOCONS_KERN_WARN
		"warning: bad address for port_info struct (%s) in %s\n";
	static const char *badmagic = VIOCONS_KERN_WARN
		"warning: bad magic number for port_info struct (%s) in %s\n";

	if ((pi < &port_info[0]) || (viochar_port(pi) > VTTY_PORTS)) {
		printk(bad_pi_addr, name, routine);
		return 1;
	}
	if (pi->magic != VIOTTY_MAGIC) {
		printk(badmagic, name, routine);
		return 1;
	}
	return 0;
}

/*
 * Add data to our pending-send buffers.  
 *
 * NOTE: Don't use printk in here because it gets nastily recursive.
 * hvlog can be used to log to the hypervisor buffer
 */
static int buffer_add(struct port_info *pi, const char *buf, size_t len)
{
	size_t bleft;
	size_t curlen;
	const char *curbuf;
	int nextbuf;

	curbuf = buf;
	bleft = len;
	while (bleft > 0) {
		/*
		 * If there is no space left in the current buffer, we have
		 * filled everything up, so return.  If we filled the previous
		 * buffer we would already have moved to the next one.
		 */
		if (pi->bufferBytes[pi->curbuf] == VIOCHAR_MAX_DATA) {
			hvlog ("\n\rviocons: No overflow buffer available for memcpy().\n");
			pi->bufferOverflow++;
			pi->overflowMessage = 1;
			break;
		}

		/*
		 * Turn on the "used" bit for this buffer.  If it's already on,
		 * that's fine.
		 */
		set_bit(pi->curbuf, &pi->used);

		/*
		 * See if this buffer has been allocated.  If not, allocate it.
		 */
		if (pi->buffer[pi->curbuf] == NULL) {
			pi->buffer[pi->curbuf] =
			    kmalloc(VIOCHAR_MAX_DATA, GFP_ATOMIC);
			if (pi->buffer[pi->curbuf] == NULL) {
				hvlog("\n\rviocons: kmalloc failed allocating spaces for buffer %d.",
					pi->curbuf);
				break;
			}
		}

		/* Figure out how much we can copy into this buffer. */
		if (bleft < (VIOCHAR_MAX_DATA - pi->bufferBytes[pi->curbuf]))
			curlen = bleft;
		else
			curlen = VIOCHAR_MAX_DATA - pi->bufferBytes[pi->curbuf];

		/* Copy the data into the buffer. */
		memcpy(pi->buffer[pi->curbuf] + pi->bufferBytes[pi->curbuf],
				curbuf, curlen);

		pi->bufferBytes[pi->curbuf] += curlen;
		curbuf += curlen;
		bleft -= curlen;

		/*
		 * Now see if we've filled this buffer.  If not then
		 * we'll try to use it again later.  If we've filled it
		 * up then we'll advance the curbuf to the next in the
		 * circular queue.
		 */
		if (pi->bufferBytes[pi->curbuf] == VIOCHAR_MAX_DATA) {
			nextbuf = (pi->curbuf + 1) % VIOCHAR_NUM_BUF;
			/*
			 * Move to the next buffer if it hasn't been used yet
			 */
			if (test_bit(nextbuf, &pi->used) == 0)
				pi->curbuf = nextbuf;
		}
	}
	return len - bleft;
}

/*
 * Send pending data
 *
 * NOTE: Don't use printk in here because it gets nastily recursive.
 * hvlog can be used to log to the hypervisor buffer
 */
static void send_buffers(struct port_info *pi)
{
	HvLpEvent_Rc hvrc;
	int nextbuf;
	struct viocharlpevent *viochar;
	unsigned long flags;

	spin_lock_irqsave(&consolelock, flags);

	viochar = (struct viocharlpevent *)
	    vio_get_event_buffer(viomajorsubtype_chario);

	/* Make sure we got a buffer */
	if (viochar == NULL) {
		hvlog("\n\rviocons: Can't get viochar buffer in sendBuffers().");
		spin_unlock_irqrestore(&consolelock, flags);
		return;
	}

	if (pi->used == 0) {
		hvlog("\n\rviocons: in sendbuffers(), but no buffers used.\n");
		vio_free_event_buffer(viomajorsubtype_chario, viochar);
		spin_unlock_irqrestore(&consolelock, flags);
		return;
	}

	/*
	 * curbuf points to the buffer we're filling.  We want to
	 * start sending AFTER this one.  
	 */
	nextbuf = (pi->curbuf + 1) % VIOCHAR_NUM_BUF;

	/*
	 * Loop until we find a buffer with the used bit on
	 */
	while (test_bit(nextbuf, &pi->used) == 0)
		nextbuf = (nextbuf + 1) % VIOCHAR_NUM_BUF;

	initDataEvent(viochar, pi->lp);

	/*
	 * While we have buffers with data, and our send window
	 * is open, send them
	 */
	while ((test_bit(nextbuf, &pi->used)) &&
	       ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) {
		viochar->len = pi->bufferBytes[nextbuf];
		viochar->event.xCorrelationToken = pi->seq++;
		viochar->event.xSizeMinus1 =
			offsetof(struct viocharlpevent, data) + viochar->len;

		memcpy(viochar->data, pi->buffer[nextbuf], viochar->len);

		hvrc = HvCallEvent_signalLpEvent(&viochar->event);
		if (hvrc) {
			/*
			 * MUST unlock the spinlock before doing a printk
			 */
			vio_free_event_buffer(viomajorsubtype_chario, viochar);
			spin_unlock_irqrestore(&consolelock, flags);

			printk(VIOCONS_KERN_WARN
			       "error sending event! return code %d\n",
			       (int)hvrc);
			return;
		}

		/*
		 * clear the used bit, zero the number of bytes in
		 * this buffer, and move to the next buffer
		 */
		clear_bit(nextbuf, &pi->used);
		pi->bufferBytes[nextbuf] = 0;
		nextbuf = (nextbuf + 1) % VIOCHAR_NUM_BUF;
	}

	/*
	 * If we have emptied all the buffers, start at 0 again.
	 * this will re-use any allocated buffers
	 */
	if (pi->used == 0) {
		pi->curbuf = 0;

		if (pi->overflowMessage)
			pi->overflowMessage = 0;

		if (pi->tty) {
			tty_wakeup(pi->tty);
		}
	}

	vio_free_event_buffer(viomajorsubtype_chario, viochar);
	spin_unlock_irqrestore(&consolelock, flags);
}

/*
 * Our internal writer.  Gets called both from the console device and
 * the tty device.  the tty pointer will be NULL if called from the console.
 * Return total number of bytes "written".
 *
 * NOTE: Don't use printk in here because it gets nastily recursive.  hvlog
 * can be used to log to the hypervisor buffer
 */
static int internal_write(struct port_info *pi, const char *buf, size_t len)
{
	HvLpEvent_Rc hvrc;
	size_t bleft;
	size_t curlen;
	const char *curbuf;
	unsigned long flags;
	struct viocharlpevent *viochar;

	/*
	 * Write to the hvlog of inbound data are now done prior to
	 * calling internal_write() since internal_write() is only called in
	 * the event that an lp event path is active, which isn't the case for
	 * logging attempts prior to console initialization.
	 *
	 * If there is already data queued for this port, send it prior to
	 * attempting to send any new data.
	 */
	if (pi->used)
		send_buffers(pi);

	spin_lock_irqsave(&consolelock, flags);

	viochar = vio_get_event_buffer(viomajorsubtype_chario);
	if (viochar == NULL) {
		spin_unlock_irqrestore(&consolelock, flags);
		hvlog("\n\rviocons: Can't get vio buffer in internal_write().");
		return -EAGAIN;
	}
	initDataEvent(viochar, pi->lp);

	curbuf = buf;
	bleft = len;

	while ((bleft > 0) && (pi->used == 0) &&
	       ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) {
		if (bleft > VIOCHAR_MAX_DATA)
			curlen = VIOCHAR_MAX_DATA;
		else
			curlen = bleft;

		viochar->event.xCorrelationToken = pi->seq++;
		memcpy(viochar->data, curbuf, curlen);
		viochar->len = curlen;
		viochar->event.xSizeMinus1 =
		    offsetof(struct viocharlpevent, data) + curlen;

		hvrc = HvCallEvent_signalLpEvent(&viochar->event);
		if (hvrc) {
			hvlog("viocons: error sending event! %d\n", (int)hvrc);
			goto out;
		}
		curbuf += curlen;
		bleft -= curlen;
	}

	/* If we didn't send it all, buffer as much of it as we can. */
	if (bleft > 0)
		bleft -= buffer_add(pi, curbuf, bleft);
out:
	vio_free_event_buffer(viomajorsubtype_chario, viochar);
	spin_unlock_irqrestore(&consolelock, flags);
	return len - bleft;
}

static struct port_info *get_port_data(struct tty_struct *tty)
{
	unsigned long flags;
	struct port_info *pi;

	spin_lock_irqsave(&consolelock, flags);
	if (tty) {
		pi = (struct port_info *)tty->driver_data;
		if (!pi || viotty_paranoia_check(pi, tty->name,
					     "get_port_data")) {
			pi = NULL;
		}
	} else
		/*
		 * If this is the console device, use the lp from
		 * the first port entry
		 */
		pi = &port_info[0];
	spin_unlock_irqrestore(&consolelock, flags);
	return pi;
}

/*
 * Initialize the common fields in a charLpEvent
 */
static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp)
{
	struct HvLpEvent *hev = &viochar->event;

	memset(viochar, 0, sizeof(struct viocharlpevent));

	hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK |
		HV_LP_EVENT_INT;
	hev->xType = HvLpEvent_Type_VirtualIo;
	hev->xSubtype = viomajorsubtype_chario | viochardata;
	hev->xSourceLp = HvLpConfig_getLpIndex();
	hev->xTargetLp = lp;
	hev->xSizeMinus1 = sizeof(struct viocharlpevent);
	hev->xSourceInstanceId = viopath_sourceinst(lp);
	hev->xTargetInstanceId = viopath_targetinst(lp);
}

/*
 * early console device write
 */
static void viocons_write_early(struct console *co, const char *s, unsigned count)
{
	hvlogOutput(s, count);
}

/*
 * console device write
 */
static void viocons_write(struct console *co, const char *s, unsigned count)
{
	int index;
	int begin;
	struct port_info *pi;

	static const char cr = '\r';

	/*
	 * Check port data first because the target LP might be valid but
	 * simply not active, in which case we want to hvlog the output.
	 */
	pi = get_port_data(NULL);
	if (pi == NULL) {
		hvlog("\n\rviocons_write: unable to get port data.");
		return;
	}

	hvlogOutput(s, count);

	if (!viopath_isactive(pi->lp))
		return;

	/* 
	 * Any newline character found will cause a
	 * carriage return character to be emitted as well. 
	 */
	begin = 0;
	for (index = 0; index < count; index++) {
		if (s[index] == '\n') {
			/* 
			 * Newline found. Print everything up to and 
			 * including the newline
			 */
			internal_write(pi, &s[begin], index - begin + 1);
			begin = index + 1;
			/* Emit a carriage return as well */
			internal_write(pi, &cr, 1);
		}
	}

	/* If any characters left to write, write them now */
	if ((index - begin) > 0)
		internal_write(pi, &s[begin], index - begin);
}

/*
 * Work out the device associate with this console
 */
static struct tty_driver *viocons_device(struct console *c, int *index)
{
	*index = c->index;
	return viotty_driver;
}

/*
 * console device I/O methods
 */
static struct console viocons_early = {
	.name = "viocons",
	.write = viocons_write_early,
	.flags = CON_PRINTBUFFER,
	.index = -1,
};

static struct console viocons = {
	.name = "viocons",
	.write = viocons_write,
	.device = viocons_device,
	.flags = CON_PRINTBUFFER,
	.index = -1,
};

/*
 * TTY Open method
 */
static int viotty_open(struct tty_struct *tty, struct file *filp)
{
	int port;
	unsigned long flags;
	struct port_info *pi;

	port = tty->index;

	if ((port < 0) || (port >= VTTY_PORTS))
		return -ENODEV;

	spin_lock_irqsave(&consolelock, flags);

	pi = &port_info[port];
	/* If some other TTY is already connected here, reject the open */
	if ((pi->tty) && (pi->tty != tty)) {
		spin_unlock_irqrestore(&consolelock, flags);
		printk(VIOCONS_KERN_WARN
		       "attempt to open device twice from different ttys\n");
		return -EBUSY;
	}
	tty->driver_data = pi;
	pi->tty = tty;
	spin_unlock_irqrestore(&consolelock, flags);

	return 0;
}

/*
 * TTY Close method
 */
static void viotty_close(struct tty_struct *tty, struct file *filp)
{
	unsigned long flags;
	struct port_info *pi;

	spin_lock_irqsave(&consolelock, flags);
	pi = (struct port_info *)tty->driver_data;

	if (!pi || viotty_paranoia_check(pi, tty->name, "viotty_close")) {
		spin_unlock_irqrestore(&consolelock, flags);
		return;
	}
	if (tty->count == 1)
		pi->tty = NULL;
	spin_unlock_irqrestore(&consolelock, flags);
}

/*
 * TTY Write method
 */
static int viotty_write(struct tty_struct *tty, const unsigned char *buf,
		int count)
{
	struct port_info *pi;

	pi = get_port_data(tty);
	if (pi == NULL) {
		hvlog("\n\rviotty_write: no port data.");
		return -ENODEV;
	}

	if (viochar_is_console(pi))
		hvlogOutput(buf, count);

	/*
	 * If the path to this LP is closed, don't bother doing anything more.
	 * just dump the data on the floor and return count.  For some reason
	 * some user level programs will attempt to probe available tty's and
	 * they'll attempt a viotty_write on an invalid port which maps to an
	 * invalid target lp.  If this is the case then ignore the
	 * viotty_write call and, since the viopath isn't active to this
	 * partition, return count.
	 */
	if (!viopath_isactive(pi->lp))
		return count;

	return internal_write(pi, buf, count);
}

/*
 * TTY put_char method
 */
static void viotty_put_char(struct tty_struct *tty, unsigned char ch)
{
	struct port_info *pi;

	pi = get_port_data(tty);
	if (pi == NULL)
		return;

	/* This will append '\r' as well if the char is '\n' */
	if (viochar_is_console(pi))
		hvlogOutput(&ch, 1);

	if (viopath_isactive(pi->lp))
		internal_write(pi, &ch, 1);
}

/*
 * TTY write_room method
 */
static int viotty_write_room(struct tty_struct *tty)
{
	int i;
	int room = 0;
	struct port_info *pi;
	unsigned long flags;

	spin_lock_irqsave(&consolelock, flags);
	pi = (struct port_info *)tty->driver_data;
	if (!pi || viotty_paranoia_check(pi, tty->name, "viotty_write_room")) {
		spin_unlock_irqrestore(&consolelock, flags);
		return 0;
	}

	/* If no buffers are used, return the max size. */
	if (pi->used == 0) {
		spin_unlock_irqrestore(&consolelock, flags);
		return VIOCHAR_MAX_DATA * VIOCHAR_NUM_BUF;
	}

	/*
	 * We retain the spinlock because we want to get an accurate
	 * count and it can change on us between each operation if we
	 * don't hold the spinlock.
	 */
	for (i = 0; ((i < VIOCHAR_NUM_BUF) && (room < VIOCHAR_MAX_DATA)); i++)
		room += (VIOCHAR_MAX_DATA - pi->bufferBytes[i]);
	spin_unlock_irqrestore(&consolelock, flags);

	if (room > VIOCHAR_MAX_DATA)
		room = VIOCHAR_MAX_DATA;
	return room;
}

/*
 * TTY chars_in_buffer method
 */
static int viotty_chars_in_buffer(struct tty_struct *tty)
{
	return 0;
}

static int viotty_ioctl(struct tty_struct *tty, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	/*
	 * the ioctls below read/set the flags usually shown in the leds
	 * don't use them - they will go away without warning
	 */
	case KDGETLED:
	case KDGKBLED:
		return put_user(0, (char *)arg);

	case KDSKBLED:
		return 0;
	}

	return n_tty_ioctl(tty, file, cmd, arg);
}

/*
 * Handle an open charLpEvent.  Could be either interrupt or ack
 */
static void vioHandleOpenEvent(struct HvLpEvent *event)
{
	unsigned long flags;
	struct viocharlpevent *cevent = (struct viocharlpevent *)event;
	u8 port = cevent->virtual_device;
	struct port_info *pi;
	int reject = 0;

	if (hvlpevent_is_ack(event)) {
		if (port >= VTTY_PORTS)
			return;

		spin_lock_irqsave(&consolelock, flags);
		/* Got the lock, don't cause console output */

		pi = &port_info[port];
		if (event->xRc == HvLpEvent_Rc_Good) {
			pi->seq = pi->ack = 0;
			/*
			 * This line allows connections from the primary
			 * partition but once one is connected from the
			 * primary partition nothing short of a reboot
			 * of linux will allow access from the hosting
			 * partition again without a required iSeries fix.
			 */
			pi->lp = event->xTargetLp;
		}

		spin_unlock_irqrestore(&consolelock, flags);
		if (event->xRc != HvLpEvent_Rc_Good)
			printk(VIOCONS_KERN_WARN
			       "handle_open_event: event->xRc == (%d).\n",
			       event->xRc);

		if (event->xCorrelationToken != 0) {
			atomic_t *aptr= (atomic_t *)event->xCorrelationToken;
			atomic_set(aptr, 1);
		} else
			printk(VIOCONS_KERN_WARN
			       "weird...got open ack without atomic\n");
		return;
	}

	/* This had better require an ack, otherwise complain */
	if (!hvlpevent_need_ack(event)) {
		printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n");
		return;
	}

	spin_lock_irqsave(&consolelock, flags);
	/* Got the lock, don't cause console output */

	/* Make sure this is a good virtual tty */
	if (port >= VTTY_PORTS) {
		event->xRc = HvLpEvent_Rc_SubtypeError;
		cevent->subtype_result_code = viorc_openRejected;
		/*
		 * Flag state here since we can't printk while holding
		 * a spinlock.
		 */
		reject = 1;
	} else {
		pi = &port_info[port];
		if ((pi->lp != HvLpIndexInvalid) &&
				(pi->lp != event->xSourceLp)) {
			/*
			 * If this is tty is already connected to a different
			 * partition, fail.
			 */
			event->xRc = HvLpEvent_Rc_SubtypeError;
			cevent->subtype_result_code = viorc_openRejected;
			reject = 2;
		} else {
			pi->lp = event->xSourceLp;
			event->xRc = HvLpEvent_Rc_Good;
			cevent->subtype_result_code = viorc_good;
			pi->seq = pi->ack = 0;
			reject = 0;
		}
	}

	spin_unlock_irqrestore(&consolelock, flags);

	if (reject == 1)
		printk(VIOCONS_KERN_WARN "open rejected: bad virtual tty.\n");
	else if (reject == 2)
		printk(VIOCONS_KERN_WARN
			"open rejected: console in exclusive use by another partition.\n");

	/* Return the acknowledgement */
	HvCallEvent_ackLpEvent(event);
}

/*
 * Handle a close charLpEvent.  This should ONLY be an Interrupt because the
 * virtual console should never actually issue a close event to the hypervisor
 * because the virtual console never goes away.  A close event coming from the
 * hypervisor simply means that there are no client consoles connected to the
 * virtual console.
 *
 * Regardless of the number of connections masqueraded on the other side of
 * the hypervisor ONLY ONE close event should be called to accompany the ONE
 * open event that is called.  The close event should ONLY be called when NO
 * MORE connections (masqueraded or not) exist on the other side of the
 * hypervisor.
 */
static void vioHandleCloseEvent(struct HvLpEvent *event)
{
	unsigned long flags;
	struct viocharlpevent *cevent = (struct viocharlpevent *)event;
	u8 port = cevent->virtual_device;

	if (hvlpevent_is_int(event)) {
		if (port >= VTTY_PORTS) {
			printk(VIOCONS_KERN_WARN
					"close message from invalid virtual device.\n");
			return;
		}

		/* For closes, just mark the console partition invalid */
		spin_lock_irqsave(&consolelock, flags);
		/* Got the lock, don't cause console output */

		if (port_info[port].lp == event->xSourceLp)
			port_info[port].lp = HvLpIndexInvalid;

		spin_unlock_irqrestore(&consolelock, flags);
		printk(VIOCONS_KERN_INFO "close from %d\n", event->xSourceLp);
	} else
		printk(VIOCONS_KERN_WARN
				"got unexpected close acknowlegement\n");
}

/*
 * Handle a config charLpEvent.  Could be either interrupt or ack
 */
static void vioHandleConfig(struct HvLpEvent *event)
{
	struct viocharlpevent *cevent = (struct viocharlpevent *)event;

	HvCall_writeLogBuffer(cevent->data, cevent->len);

	if (cevent->data[0] == 0x01)
		printk(VIOCONS_KERN_INFO "window resized to %d: %d: %d: %d\n",
		       cevent->data[1], cevent->data[2],
		       cevent->data[3], cevent->data[4]);
	else
		printk(VIOCONS_KERN_WARN "unknown config event\n");
}

/*
 * Handle a data charLpEvent. 
 */
static void vioHandleData(struct HvLpEvent *event)
{
	struct tty_struct *tty;
	unsigned long flags;
	struct viocharlpevent *cevent = (struct viocharlpevent *)event;
	struct port_info *pi;
	int index;
	int num_pushed;
	u8 port = cevent->virtual_device;

	if (port >= VTTY_PORTS) {
		printk(VIOCONS_KERN_WARN "data on invalid virtual device %d\n",
				port);
		return;
	}

	/*
	 * Hold the spinlock so that we don't take an interrupt that
	 * changes tty between the time we fetch the port_info
	 * pointer and the time we paranoia check.
	 */
	spin_lock_irqsave(&consolelock, flags);
	pi = &port_info[port];

	/*
	 * Change 05/01/2003 - Ryan Arnold: If a partition other than
	 * the current exclusive partition tries to send us data
	 * events then just drop them on the floor because we don't
	 * want his stinking data.  He isn't authorized to receive
	 * data because he wasn't the first one to get the console,
	 * therefore he shouldn't be allowed to send data either.
	 * This will work without an iSeries fix.
	 */
	if (pi->lp != event->xSourceLp) {
		spin_unlock_irqrestore(&consolelock, flags);
		return;
	}

	tty = pi->tty;
	if (tty == NULL) {
		spin_unlock_irqrestore(&consolelock, flags);
		printk(VIOCONS_KERN_WARN "no tty for virtual device %d\n",
				port);
		return;
	}

	if (tty->magic != TTY_MAGIC) {
		spin_unlock_irqrestore(&consolelock, flags);
		printk(VIOCONS_KERN_WARN "tty bad magic\n");
		return;
	}

	/*
	 * Just to be paranoid, make sure the tty points back to this port
	 */
	pi = (struct port_info *)tty->driver_data;
	if (!pi || viotty_paranoia_check(pi, tty->name, "vioHandleData")) {
		spin_unlock_irqrestore(&consolelock, flags);
		return;
	}
	spin_unlock_irqrestore(&consolelock, flags);

	/*
	 * Change 07/21/2003 - Ryan Arnold: functionality added to
	 * support sysrq utilizing ^O as the sysrq key.  The sysrq
	 * functionality will only work if built into the kernel and
	 * then only if sysrq is enabled through the proc filesystem.
	 */
	num_pushed = 0;
	for (index = 0; index < cevent->len; index++) {
#ifdef CONFIG_MAGIC_SYSRQ
		if (sysrq_enabled) {
			/* 0x0f is the ascii character for ^O */
			if (cevent->data[index] == '\x0f') {
				vio_sysrq_pressed = 1;
				/*
				 * continue because we don't want to add
				 * the sysrq key into the data string.
				 */
				continue;
			} else if (vio_sysrq_pressed) {
				handle_sysrq(cevent->data[index], NULL, tty);
				vio_sysrq_pressed = 0;
				/*
				 * continue because we don't want to add
				 * the sysrq sequence into the data string.
				 */
				continue;
			}
		}
#endif
		/*
		 * The sysrq sequence isn't included in this check if
		 * sysrq is enabled and compiled into the kernel because
		 * the sequence will never get inserted into the buffer.
		 * Don't attempt to copy more data into the buffer than we
		 * have room for because it would fail without indication.
		 */
		if(tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL) == 0) {
			printk(VIOCONS_KERN_WARN "input buffer overflow!\n");
			break;
		}
		num_pushed++;
	}

	if (num_pushed)
		tty_flip_buffer_push(tty);
}

/*
 * Handle an ack charLpEvent. 
 */
static void vioHandleAck(struct HvLpEvent *event)
{
	struct viocharlpevent *cevent = (struct viocharlpevent *)event;
	unsigned long flags;
	u8 port = cevent->virtual_device;

	if (port >= VTTY_PORTS) {
		printk(VIOCONS_KERN_WARN "data on invalid virtual device\n");
		return;
	}

	spin_lock_irqsave(&consolelock, flags);
	port_info[port].ack = event->xCorrelationToken;
	spin_unlock_irqrestore(&consolelock, flags);

	if (port_info[port].used)
		send_buffers(&port_info[port]);
}

/*
 * Handle charLpEvents and route to the appropriate routine
 */
static void vioHandleCharEvent(struct HvLpEvent *event)
{
	int charminor;

	if (event == NULL)
		return;

	charminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
	switch (charminor) {
	case viocharopen:
		vioHandleOpenEvent(event);
		break;
	case viocharclose:
		vioHandleCloseEvent(event);
		break;
	case viochardata:
		vioHandleData(event);
		break;
	case viocharack:
		vioHandleAck(event);
		break;
	case viocharconfig:
		vioHandleConfig(event);
		break;
	default:
		if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
			event->xRc = HvLpEvent_Rc_InvalidSubtype;
			HvCallEvent_ackLpEvent(event);
		}
	}
}

/*
 * Send an open event
 */
static int send_open(HvLpIndex remoteLp, void *sem)
{
	return HvCallEvent_signalLpEventFast(remoteLp,
			HvLpEvent_Type_VirtualIo,
			viomajorsubtype_chario | viocharopen,
			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
			viopath_sourceinst(remoteLp),
			viopath_targetinst(remoteLp),
			(u64)(unsigned long)sem, VIOVERSION << 16,
			0, 0, 0, 0);
}

static struct tty_operations serial_ops = {
	.open = viotty_open,
	.close = viotty_close,
	.write = viotty_write,
	.put_char = viotty_put_char,
	.write_room = viotty_write_room,
	.chars_in_buffer = viotty_chars_in_buffer,
	.ioctl = viotty_ioctl,
};

static int __init viocons_init2(void)
{
	atomic_t wait_flag;
	int rc;

	/* +2 for fudge */
	rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
			viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
	if (rc)
		printk(VIOCONS_KERN_WARN "error opening to primary %d\n", rc);

	if (viopath_hostLp == HvLpIndexInvalid)
		vio_set_hostlp();

	/*
	 * And if the primary is not the same as the hosting LP, open to the 
	 * hosting lp
	 */
	if ((viopath_hostLp != HvLpIndexInvalid) &&
	    (viopath_hostLp != HvLpConfig_getPrimaryLpIndex())) {
		printk(VIOCONS_KERN_INFO "open path to hosting (%d)\n",
				viopath_hostLp);
		rc = viopath_open(viopath_hostLp, viomajorsubtype_chario,
				VIOCHAR_WINDOW + 2);	/* +2 for fudge */
		if (rc)
			printk(VIOCONS_KERN_WARN
				"error opening to partition %d: %d\n",
				viopath_hostLp, rc);
	}

	if (vio_setHandler(viomajorsubtype_chario, vioHandleCharEvent) < 0)
		printk(VIOCONS_KERN_WARN
				"error seting handler for console events!\n");

	/*
	 * First, try to open the console to the hosting lp.
	 * Wait on a semaphore for the response.
	 */
	atomic_set(&wait_flag, 0);
	if ((viopath_isactive(viopath_hostLp)) &&
	    (send_open(viopath_hostLp, (void *)&wait_flag) == 0)) {
		printk(VIOCONS_KERN_INFO "hosting partition %d\n",
			viopath_hostLp);
		while (atomic_read(&wait_flag) == 0)
			mb();
		atomic_set(&wait_flag, 0);
	}

	/*
	 * If we don't have an active console, try the primary
	 */
	if ((!viopath_isactive(port_info[0].lp)) &&
	    (viopath_isactive(HvLpConfig_getPrimaryLpIndex())) &&
	    (send_open(HvLpConfig_getPrimaryLpIndex(), (void *)&wait_flag)
	     == 0)) {
		printk(VIOCONS_KERN_INFO "opening console to primary partition\n");
		while (atomic_read(&wait_flag) == 0)
			mb();
	}

	/* Initialize the tty_driver structure */
	viotty_driver = alloc_tty_driver(VTTY_PORTS);
	viotty_driver->owner = THIS_MODULE;
	viotty_driver->driver_name = "vioconsole";
	viotty_driver->name = "tty";
	viotty_driver->name_base = 1;
	viotty_driver->major = TTY_MAJOR;
	viotty_driver->minor_start = 1;
	viotty_driver->type = TTY_DRIVER_TYPE_CONSOLE;
	viotty_driver->subtype = 1;
	viotty_driver->init_termios = tty_std_termios;
	viotty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
	tty_set_operations(viotty_driver, &serial_ops);

	if (tty_register_driver(viotty_driver)) {
		printk(VIOCONS_KERN_WARN "couldn't register console driver\n");
		put_tty_driver(viotty_driver);
		viotty_driver = NULL;
	}

	unregister_console(&viocons_early);
	register_console(&viocons);

	return 0;
}

static int __init viocons_init(void)
{
	int i;

	printk(VIOCONS_KERN_INFO "registering console\n");
	for (i = 0; i < VTTY_PORTS; i++) {
		port_info[i].lp = HvLpIndexInvalid;
		port_info[i].magic = VIOTTY_MAGIC;
	}
	HvCall_setLogBufferFormatAndCodepage(HvCall_LogBuffer_ASCII, 437);
	add_preferred_console("viocons", 0, NULL);
	register_console(&viocons_early);
	return 0;
}

console_initcall(viocons_init);
module_init(viocons_init2);
