/*
 * iSeries vio driver interface to hvc_console.c
 *
 * This code is based heavily on hvc_vio.c and viocons.c
 *
 * Copyright (C) 2006 Stephen Rothwell, 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) any 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 <stdarg.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/console.h>

#include <asm/hvconsole.h>
#include <asm/vio.h>
#include <asm/prom.h>
#include <asm/firmware.h>
#include <asm/iseries/vio.h>
#include <asm/iseries/hv_call.h>
#include <asm/iseries/hv_lp_config.h>
#include <asm/iseries/hv_lp_event.h>

#include "hvc_console.h"

#define VTTY_PORTS 10

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

static const char hvc_driver_name[] = "hvc_console";

#define IN_BUF_SIZE	200

/*
 * Our port information.
 */
static struct port_info {
	HvLpIndex lp;
	u64 seq;	/* sequence number of last HV send */
	u64 ack;	/* last ack from HV */
	struct hvc_struct *hp;
	int in_start;
	int in_end;
	unsigned char in_buf[IN_BUF_SIZE];
} port_info[VTTY_PORTS] = {
	[ 0 ... VTTY_PORTS - 1 ] = {
		.lp = HvLpIndexInvalid
	}
};

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

static struct vio_device_id hvc_driver_table[] __devinitdata = {
	{"serial", "IBM,iSeries-vty"},
	{ "", "" }
};
MODULE_DEVICE_TABLE(vio, hvc_driver_table);

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

/*
 * Initialize the common fields in a charLpEvent
 */
static void init_data_event(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);
}

static int get_chars(uint32_t vtermno, char *buf, int count)
{
	struct port_info *pi;
	int n = 0;
	unsigned long flags;

	if (vtermno >= VTTY_PORTS)
		return -EINVAL;
	if (count == 0)
		return 0;

	pi = &port_info[vtermno];
	spin_lock_irqsave(&consolelock, flags);

	if (pi->in_end == 0)
		goto done;

	n = pi->in_end - pi->in_start;
	if (n > count)
		n = count;
	memcpy(buf, &pi->in_buf[pi->in_start], n);
	pi->in_start += n;
	if (pi->in_start == pi->in_end) {
		pi->in_start = 0;
		pi->in_end = 0;
	}
done:
	spin_unlock_irqrestore(&consolelock, flags);
	return n;
}

static int put_chars(uint32_t vtermno, const char *buf, int count)
{
	struct viocharlpevent *viochar;
	struct port_info *pi;
	HvLpEvent_Rc hvrc;
	unsigned long flags;
	int sent = 0;

	if (vtermno >= VTTY_PORTS)
		return -EINVAL;

	pi = &port_info[vtermno];

	spin_lock_irqsave(&consolelock, flags);

	if (viochar_is_console(pi) && !viopath_isactive(pi->lp)) {
		HvCall_writeLogBuffer(buf, count);
		sent = count;
		goto done;
	}

	viochar = vio_get_event_buffer(viomajorsubtype_chario);
	if (viochar == NULL) {
		hvlog("\n\rviocons: Can't get viochar buffer.");
		goto done;
	}

	while ((count > 0) && ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) {
		int len;

		len = (count > VIOCHAR_MAX_DATA) ? VIOCHAR_MAX_DATA : count;

		if (viochar_is_console(pi))
			HvCall_writeLogBuffer(buf, len);

		init_data_event(viochar, pi->lp);

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

		memcpy(viochar->data, buf, len);

		hvrc = HvCallEvent_signalLpEvent(&viochar->event);
		if (hvrc)
			hvlog("\n\rerror sending event! return code %d\n\r",
				(int)hvrc);
		sent += len;
		count -= len;
		buf += len;
	}

	vio_free_event_buffer(viomajorsubtype_chario, viochar);
done:
	spin_unlock_irqrestore(&consolelock, flags);
	return sent;
}

static struct hv_ops hvc_get_put_ops = {
	.get_chars = get_chars,
	.put_chars = put_chars,
	.notifier_add = notifier_add_irq,
	.notifier_del = notifier_del_irq,
	.notifier_hangup = notifier_hangup_irq,
};

static int __devinit hvc_vio_probe(struct vio_dev *vdev,
			const struct vio_device_id *id)
{
	struct hvc_struct *hp;
	struct port_info *pi;

	/* probed with invalid parameters. */
	if (!vdev || !id)
		return -EPERM;

	if (vdev->unit_address >= VTTY_PORTS)
		return -ENODEV;

	pi = &port_info[vdev->unit_address];

	hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops,
			VIOCHAR_MAX_DATA);
	if (IS_ERR(hp))
		return PTR_ERR(hp);
	pi->hp = hp;
	dev_set_drvdata(&vdev->dev, pi);

	return 0;
}

static int __devexit hvc_vio_remove(struct vio_dev *vdev)
{
	struct port_info *pi = dev_get_drvdata(&vdev->dev);
	struct hvc_struct *hp = pi->hp;

	return hvc_remove(hp);
}

static struct vio_driver hvc_vio_driver = {
	.id_table	= hvc_driver_table,
	.probe		= hvc_vio_probe,
	.remove		= __devexit_p(hvc_vio_remove),
	.driver		= {
		.name	= hvc_driver_name,
		.owner	= THIS_MODULE,
	}
};

static void hvc_open_event(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);

		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(KERN_WARNING
			       "hvc: 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(KERN_WARNING
			       "hvc: weird...got open ack without atomic\n");
		return;
	}

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

	spin_lock_irqsave(&consolelock, flags);

	/* 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
		 * the consolelock 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;
		}
	}

	spin_unlock_irqrestore(&consolelock, flags);

	if (reject == 1)
		printk(KERN_WARNING "hvc: open rejected: bad virtual tty.\n");
	else if (reject == 2)
		printk(KERN_WARNING "hvc: 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.
 */
static void hvc_close_event(struct HvLpEvent *event)
{
	unsigned long flags;
	struct viocharlpevent *cevent = (struct viocharlpevent *)event;
	u8 port = cevent->virtual_device;

	if (!hvlpevent_is_int(event)) {
		printk(KERN_WARNING
			"hvc: got unexpected close acknowlegement\n");
		return;
	}

	if (port >= VTTY_PORTS) {
		printk(KERN_WARNING
			"hvc: close message from invalid virtual device.\n");
		return;
	}

	/* For closes, just mark the console partition invalid */
	spin_lock_irqsave(&consolelock, flags);

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

	spin_unlock_irqrestore(&consolelock, flags);
}

static void hvc_data_event(struct HvLpEvent *event)
{
	unsigned long flags;
	struct viocharlpevent *cevent = (struct viocharlpevent *)event;
	struct port_info *pi;
	int n;
	u8 port = cevent->virtual_device;

	if (port >= VTTY_PORTS) {
		printk(KERN_WARNING "hvc: data on invalid virtual device %d\n",
				port);
		return;
	}
	if (cevent->len == 0)
		return;

	/*
	 * 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.
	 */
	pi = &port_info[port];
	if (pi->lp != event->xSourceLp)
		return;

	spin_lock_irqsave(&consolelock, flags);

	n = IN_BUF_SIZE - pi->in_end;
	if (n > cevent->len)
		n = cevent->len;
	if (n > 0) {
		memcpy(&pi->in_buf[pi->in_end], cevent->data, n);
		pi->in_end += n;
	}
	spin_unlock_irqrestore(&consolelock, flags);
	if (n == 0)
		printk(KERN_WARNING "hvc: input buffer overflow\n");
}

static void hvc_ack_event(struct HvLpEvent *event)
{
	struct viocharlpevent *cevent = (struct viocharlpevent *)event;
	unsigned long flags;
	u8 port = cevent->virtual_device;

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

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

static void hvc_config_event(struct HvLpEvent *event)
{
	struct viocharlpevent *cevent = (struct viocharlpevent *)event;

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

static void hvc_handle_event(struct HvLpEvent *event)
{
	int charminor;

	if (event == NULL)
		return;

	charminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
	switch (charminor) {
	case viocharopen:
		hvc_open_event(event);
		break;
	case viocharclose:
		hvc_close_event(event);
		break;
	case viochardata:
		hvc_data_event(event);
		break;
	case viocharack:
		hvc_ack_event(event);
		break;
	case viocharconfig:
		hvc_config_event(event);
		break;
	default:
		if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
			event->xRc = HvLpEvent_Rc_InvalidSubtype;
			HvCallEvent_ackLpEvent(event);
		}
	}
}

static int __init 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 int __init hvc_vio_init(void)
{
	atomic_t wait_flag;
	int rc;

	if (!firmware_has_feature(FW_FEATURE_ISERIES))
		return -EIO;

	/* +2 for fudge */
	rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
			viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
	if (rc)
		printk(KERN_WARNING "hvc: 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(KERN_INFO "hvc: open path to hosting (%d)\n",
				viopath_hostLp);
		rc = viopath_open(viopath_hostLp, viomajorsubtype_chario,
				VIOCHAR_WINDOW + 2);	/* +2 for fudge */
		if (rc)
			printk(KERN_WARNING
				"error opening to partition %d: %d\n",
				viopath_hostLp, rc);
	}

	if (vio_setHandler(viomajorsubtype_chario, hvc_handle_event) < 0)
		printk(KERN_WARNING
			"hvc: 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, &wait_flag) == 0)) {
		printk(KERN_INFO "hvc: 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(), &wait_flag) == 0)) {
		printk(KERN_INFO "hvc: opening console to primary partition\n");
		while (atomic_read(&wait_flag) == 0)
			mb();
	}

	/* Register as a vio device to receive callbacks */
	rc = vio_register_driver(&hvc_vio_driver);

	return rc;
}
module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */

static void __exit hvc_vio_exit(void)
{
	vio_unregister_driver(&hvc_vio_driver);
}
module_exit(hvc_vio_exit);

/* the device tree order defines our numbering */
static int __init hvc_find_vtys(void)
{
	struct device_node *vty;
	int num_found = 0;

	for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
			vty = of_find_node_by_name(vty, "vty")) {
		const uint32_t *vtermno;

		/* We have statically defined space for only a certain number
		 * of console adapters.
		 */
		if ((num_found >= MAX_NR_HVC_CONSOLES) ||
				(num_found >= VTTY_PORTS)) {
			of_node_put(vty);
			break;
		}

		vtermno = of_get_property(vty, "reg", NULL);
		if (!vtermno)
			continue;

		if (!of_device_is_compatible(vty, "IBM,iSeries-vty"))
			continue;

		if (num_found == 0)
			add_preferred_console("hvc", 0, NULL);
		hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
		++num_found;
	}

	return num_found;
}
console_initcall(hvc_find_vtys);
