/* -*- 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/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;

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