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. */
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user