Commit 91fcad19 authored by Christian Borntraeger's avatar Christian Borntraeger Committed by Rusty Russell
Browse files

virtio_console: use virtqueue notification for hvc_console



This patch exploits the new notifier callbacks of the hvc_console. We can
use the virtio callbacks instead of the polling code.

Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 611e097d
Loading
Loading
Loading
Loading
+33 −7
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ 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
@@ -134,6 +137,27 @@ int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int))
	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.
 *
@@ -144,7 +168,6 @@ int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int))
static int __devinit virtcons_probe(struct virtio_device *dev)
{
	int err;
	struct hvc_struct *hvc;

	vdev = dev;

@@ -158,7 +181,7 @@ static int __devinit virtcons_probe(struct virtio_device *dev)
	/* 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, NULL);
	in_vq = vdev->config->find_vq(vdev, 0, hvc_handle_input);
	if (IS_ERR(in_vq)) {
		err = PTR_ERR(in_vq);
		goto free;
@@ -173,15 +196,18 @@ static int __devinit virtcons_probe(struct virtio_device *dev)
	/* 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 interrupt number; we
	 * currently leave this as zero: it would be better not to use the
	 * hvc mechanism and fix this (FIXME!).
	 * 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()
	 * and get_chars() pointers.  The final argument is the output buffer
	 * size: we can do any size, so we put PAGE_SIZE here. */
	 * 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);