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