/* -*- 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/config.h>
#include <linux/version.h>
#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

/*
 * The structure of the events that flow between us and OS/400.  You can't
 * mess with this unless the OS/400 side changes too
 */
struct viocharlpevent {
	struct HvLpEvent event;
	u32 reserved;
	u16 version;
	u16 subtype_result_code;
	u8 virtual_device;
	u8 len;
	u8 data[VIOCHAR_MAX_DATA];
};

#define VIOCHAR_WINDOW		10
#define VIOCHAR_HIGHWATERMARK	3

enum viocharsubtype {
	viocharopen = 0x0001,
	viocharclose = 0x0002,
	viochardata = 0x0003,
	viocharack = 0x0004,
	viocharconfig = 0x0005
};

enum viochar_rc {
	viochar_rc_ebusy = 1
};

#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;

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

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)
{
	memset(viochar, 0, sizeof(struct viocharlpevent));

	viochar->event.xFlags.xValid = 1;
	viochar->event.xFlags.xFunction = HvLpEvent_Function_Int;
	viochar->event.xFlags.xAckInd = HvLpEvent_AckInd_NoAck;
	viochar->event.xFlags.xAckType = HvLpEvent_AckType_DeferredAck;
	viochar->event.xType = HvLpEvent_Type_VirtualIo;
	viochar->event.xSubtype = viomajorsubtype_chario | viochardata;
	viochar->event.xSourceLp = HvLpConfig_getLpIndex();
	viochar->event.xTargetLp = lp;
	viochar->event.xSizeMinus1 = sizeof(struct viocharlpevent);
	viochar->event.xSourceInstanceId = viopath_sourceinst(lp);
	viochar->event.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 (event->xFlags.xFunction == HvLpEvent_Function_Ack) {
		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 (event->xFlags.xAckInd != HvLpEvent_AckInd_DoAck) {
		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 (event->xFlags.xFunction == HvLpEvent_Function_Int) {
		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;
	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.
	 */
	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->flip.count + 1) > TTY_FLIPBUF_SIZE) {
			printk(VIOCONS_KERN_WARN "input buffer overflow!\n");
			break;
		}
		tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL);
	}

	/* if cevent->len == 0 then no data was added to the buffer and flip.count == 0 */
	if (tty->flip.count)
		/* The next call resets flip.count when the data is flushed. */
		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 ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
		    (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
			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->devfs_name = "vcs/";
	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);
	register_console(&viocons_early);
	return 0;
}

console_initcall(viocons_init);
module_init(viocons_init2);
