|
@@ -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);
|