/*D:300
 * The Guest console driver
 *
 * Writing console drivers is one of the few remaining Dark Arts in Linux.
 * Fortunately for us, the path of virtual consoles has been well-trodden by
 * the PowerPC folks, who wrote "hvc_console.c" to generically support any
 * virtual console.  We use that infrastructure which only requires us to write
 * the basic put_chars and get_chars functions and call the right register
 * functions.
 :*/

/*M:002 The console can be flooded: while the Guest is processing input the
 * Host can send more.  Buffering in the Host could alleviate this, but it is a
 * difficult problem in general. :*/
/* Copyright (C) 2006, 2007 Rusty Russell, 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 <linux/err.h>
#include <linux/init.h>
#include <linux/virtio.h>
#include <linux/virtio_console.h>
#include "hvc_console.h"

/*D:340 These represent our input and output console queues, and the virtio
 * operations for them. */
static struct virtqueue *in_vq, *out_vq;
static struct virtio_device *vdev;

/* This is our input buffer, and how much data is left in it. */
static unsigned int in_len;
static char *in, *inbuf;

/* The operations for our console. */
static struct hv_ops virtio_cons;

/* The hvc device */
static struct hvc_struct *hvc;

/*D:310 The put_chars() callback is pretty straightforward.
 *
 * We turn the characters into a scatter-gather list, add it to the output
 * queue and then kick the Host.  Then we sit here waiting for it to finish:
 * inefficient in theory, but in practice implementations will do it
 * immediately (lguest's Launcher does). */
static int put_chars(u32 vtermno, const char *buf, int count)
{
	struct scatterlist sg[1];
	unsigned int len;

	/* This is a convenient routine to initialize a single-elem sg list */
	sg_init_one(sg, buf, count);

	/* add_buf wants a token to identify this buffer: we hand it any
	 * non-NULL pointer, since there's only ever one buffer. */
	if (out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, (void *)1) == 0) {
		/* Tell Host to go! */
		out_vq->vq_ops->kick(out_vq);
		/* Chill out until it's done with the buffer. */
		while (!out_vq->vq_ops->get_buf(out_vq, &len))
			cpu_relax();
	}

	/* We're expected to return the amount of data we wrote: all of it. */
	return count;
}

/* Create a scatter-gather list representing our input buffer and put it in the
 * queue. */
static void add_inbuf(void)
{
	struct scatterlist sg[1];
	sg_init_one(sg, inbuf, PAGE_SIZE);

	/* We should always be able to add one buffer to an empty queue. */
	if (in_vq->vq_ops->add_buf(in_vq, sg, 0, 1, inbuf) != 0)
		BUG();
	in_vq->vq_ops->kick(in_vq);
}

/*D:350 get_chars() is the callback from the hvc_console infrastructure when
 * an interrupt is received.
 *
 * Most of the code deals with the fact that the hvc_console() infrastructure
 * only asks us for 16 bytes at a time.  We keep in_offset and in_used fields
 * for partially-filled buffers. */
static int get_chars(u32 vtermno, char *buf, int count)
{
	/* If we don't have an input queue yet, we can't get input. */
	BUG_ON(!in_vq);

	/* No buffer?  Try to get one. */
	if (!in_len) {
		in = in_vq->vq_ops->get_buf(in_vq, &in_len);
		if (!in)
			return 0;
	}

	/* You want more than we have to give?  Well, try wanting less! */
	if (in_len < count)
		count = in_len;

	/* Copy across to their buffer and increment offset. */
	memcpy(buf, in, count);
	in += count;
	in_len -= count;

	/* Finished?  Re-register buffer so Host will use it again. */
	if (in_len == 0)
		add_inbuf();

	return count;
}
/*:*/

/*D:320 Console drivers are initialized very early so boot messages can go out,
 * so we do things slightly differently from the generic virtio initialization
 * of the net and block drivers.
 *
 * At this stage, the console is output-only.  It's too early to set up a
 * virtqueue, so we let the drivers do some boutique early-output thing. */
int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int))
{
	virtio_cons.put_chars = put_chars;
	return hvc_instantiate(0, 0, &virtio_cons);
}

/*
 * we support only one console, the hvc struct is a global var
 * There is no need to do anything
 */
static int notifier_add_vio(struct hvc_struct *hp, int data)
{
	hp->irq_requested = 1;
	return 0;
}

static void notifier_del_vio(struct hvc_struct *hp, int data)
{
	hp->irq_requested = 0;
}

static void hvc_handle_input(struct virtqueue *vq)
{
	if (hvc_poll(hvc))
		hvc_kick();
}

/*D:370 Once we're further in boot, we get probed like any other virtio device.
 * At this stage we set up the output virtqueue.
 *
 * To set up and manage our virtual console, we call hvc_alloc().  Since we
 * never remove the console device we never need this pointer again.
 *
 * Finally we put our input buffer in the input queue, ready to receive. */
static int __devinit virtcons_probe(struct virtio_device *dev)
{
	int err;

	vdev = dev;

	/* This is the scratch page we use to receive console input */
	inbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!inbuf) {
		err = -ENOMEM;
		goto fail;
	}

	/* Find the input queue. */
	/* FIXME: This is why we want to wean off hvc: we do nothing
	 * when input comes in. */
	in_vq = vdev->config->find_vq(vdev, 0, hvc_handle_input);
	if (IS_ERR(in_vq)) {
		err = PTR_ERR(in_vq);
		goto free;
	}

	out_vq = vdev->config->find_vq(vdev, 1, NULL);
	if (IS_ERR(out_vq)) {
		err = PTR_ERR(out_vq);
		goto free_in_vq;
	}

	/* Start using the new console output. */
	virtio_cons.get_chars = get_chars;
	virtio_cons.put_chars = put_chars;
	virtio_cons.notifier_add = notifier_add_vio;
	virtio_cons.notifier_del = notifier_del_vio;

	/* The first argument of hvc_alloc() is the virtual console number, so
	 * we use zero.  The second argument is the parameter for the
	 * notification mechanism (like irq number). We currently leave this
	 * as zero, virtqueues have implicit notifications.
	 *
	 * The third argument is a "struct hv_ops" containing the put_chars()
	 * get_chars(), notifier_add() and notifier_del() pointers.
	 * The final argument is the output buffer size: we can do any size,
	 * so we put PAGE_SIZE here. */
	hvc = hvc_alloc(0, 0, &virtio_cons, PAGE_SIZE);
	if (IS_ERR(hvc)) {
		err = PTR_ERR(hvc);
		goto free_out_vq;
	}

	/* Register the input buffer the first time. */
	add_inbuf();
	return 0;

free_out_vq:
	vdev->config->del_vq(out_vq);
free_in_vq:
	vdev->config->del_vq(in_vq);
free:
	kfree(inbuf);
fail:
	return err;
}

static struct virtio_device_id id_table[] = {
	{ VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID },
	{ 0 },
};

static struct virtio_driver virtio_console = {
	.driver.name =	KBUILD_MODNAME,
	.driver.owner =	THIS_MODULE,
	.id_table =	id_table,
	.probe =	virtcons_probe,
};

static int __init init(void)
{
	return register_virtio_driver(&virtio_console);
}
module_init(init);

MODULE_DEVICE_TABLE(virtio, id_table);
MODULE_DESCRIPTION("Virtio console driver");
MODULE_LICENSE("GPL");
