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:
parent
611e097d77
commit
91fcad19d0
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue