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: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Christian Borntraeger 2008-06-20 15:24:15 +02:00 committed by Rusty Russell
parent 611e097d77
commit 91fcad19d0
1 changed files with 33 additions and 7 deletions

View File

@ -46,6 +46,9 @@ static char *in, *inbuf;
/* The operations for our console. */ /* The operations for our console. */
static struct hv_ops virtio_cons; static struct hv_ops virtio_cons;
/* The hvc device */
static struct hvc_struct *hvc;
/*D:310 The put_chars() callback is pretty straightforward. /*D:310 The put_chars() callback is pretty straightforward.
* *
* We turn the characters into a scatter-gather list, add it to the output * 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); 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. /*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. * 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) static int __devinit virtcons_probe(struct virtio_device *dev)
{ {
int err; int err;
struct hvc_struct *hvc;
vdev = dev; vdev = dev;
@ -158,7 +181,7 @@ static int __devinit virtcons_probe(struct virtio_device *dev)
/* Find the input queue. */ /* Find the input queue. */
/* FIXME: This is why we want to wean off hvc: we do nothing /* FIXME: This is why we want to wean off hvc: we do nothing
* when input comes in. */ * 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)) { if (IS_ERR(in_vq)) {
err = PTR_ERR(in_vq); err = PTR_ERR(in_vq);
goto free; goto free;
@ -173,15 +196,18 @@ static int __devinit virtcons_probe(struct virtio_device *dev)
/* Start using the new console output. */ /* Start using the new console output. */
virtio_cons.get_chars = get_chars; virtio_cons.get_chars = get_chars;
virtio_cons.put_chars = put_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 /* The first argument of hvc_alloc() is the virtual console number, so
* we use zero. The second argument is the interrupt number; we * we use zero. The second argument is the parameter for the
* currently leave this as zero: it would be better not to use the * notification mechanism (like irq number). We currently leave this
* hvc mechanism and fix this (FIXME!). * as zero, virtqueues have implicit notifications.
* *
* The third argument is a "struct hv_ops" containing the put_chars() * The third argument is a "struct hv_ops" containing the put_chars()
* and get_chars() pointers. The final argument is the output buffer * get_chars(), notifier_add() and notifier_del() pointers.
* size: we can do any size, so we put PAGE_SIZE here. */ * 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); hvc = hvc_alloc(0, 0, &virtio_cons, PAGE_SIZE);
if (IS_ERR(hvc)) { if (IS_ERR(hvc)) {
err = PTR_ERR(hvc); err = PTR_ERR(hvc);