[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Publish the virtual console interface in public/io/console.h.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 2d2414d6f938eb82e394e555342119aa44d4b2d0
# Parent  46bd7564125d7e91832d132979bd7e4b3af27b08
Publish the virtual console interface in public/io/console.h.
Make the ring buffers a powe-of-two in size.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 46bd7564125d -r 2d2414d6f938 
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Tue Oct 11 
12:02:59 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Tue Oct 11 
13:14:54 2005
@@ -20,69 +20,48 @@
 #include <linux/sched.h>
 #include <linux/err.h>
 #include "xencons_ring.h"
-
-struct ring_head
-{
-       u32 cons;
-       u32 prod;
-       char buf[0];
-} __attribute__((packed));
+#include <asm-xen/xen-public/io/console.h>
 
 static int xencons_irq;
+static xencons_receiver_func *xencons_receiver;
 
-#define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head))
-#define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE)
-#define XENCONS_FULL(ring) (((ring)->prod - (ring)->cons) == XENCONS_RING_SIZE)
-
-static inline struct ring_head *outring(void)
+static inline struct xencons_interface *xencons_interface(void)
 {
        return mfn_to_virt(xen_start_info->console_mfn);
 }
 
-static inline struct ring_head *inring(void)
-{
-       return mfn_to_virt(xen_start_info->console_mfn) + PAGE_SIZE/2;
-}
-
-
-/* don't block -  write as much as possible and return */
-static int __xencons_ring_send(
-       struct ring_head *ring, const char *data, unsigned len)
-{
-       int copied = 0;
-
-       mb();
-       while (copied < len && !XENCONS_FULL(ring)) {
-               ring->buf[XENCONS_IDX(ring->prod)] = data[copied];
-               ring->prod++;
-               copied++;
-       }
-       mb();
-
-       return copied;
-}
-
 int xencons_ring_send(const char *data, unsigned len)
 {
-       int sent = __xencons_ring_send(outring(), data, len);
+       int sent = 0;
+       struct xencons_interface *intf = xencons_interface();
+
+       while ((sent < len) &&
+              (intf->out_prod - intf->out_cons) < sizeof(intf->out)) {
+               intf->out[MASK_XENCONS_IDX(intf->out_prod, intf->out)] =
+                       data[sent];
+               intf->out_prod++;
+               sent++;
+       }
+
        /* Use evtchn: this is called early, before irq is set up. */
        notify_remote_via_evtchn(xen_start_info->console_evtchn);
+
        return sent;
 }      
 
-
-static xencons_receiver_func *xencons_receiver;
-
 static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs)
 {
-       struct ring_head *ring = inring();
-       while (ring->cons < ring->prod) {
-               if (xencons_receiver != NULL) {
-                       xencons_receiver(ring->buf + XENCONS_IDX(ring->cons),
-                                        1, regs);
-               }
-               ring->cons++;
+       struct xencons_interface *intf = xencons_interface();
+
+       while (intf->in_cons != intf->in_prod) {
+               if (xencons_receiver != NULL)
+                       xencons_receiver(
+                               intf->in + MASK_XENCONS_IDX(intf->in_cons,
+                                                           intf->in),
+                               1, regs);
+               intf->in_cons++;
        }
+
        return IRQ_HANDLED;
 }
 
@@ -96,7 +75,7 @@
        int err;
 
        if (xencons_irq)
-               unbind_evtchn_from_irqhandler(xencons_irq, inring());
+               unbind_evtchn_from_irqhandler(xencons_irq, NULL);
        xencons_irq = 0;
 
        if (!xen_start_info->console_evtchn)
@@ -104,7 +83,7 @@
 
        err = bind_evtchn_to_irqhandler(
                xen_start_info->console_evtchn,
-               handle_input, 0, "xencons", inring());
+               handle_input, 0, "xencons", NULL);
        if (err <= 0) {
                xprintk("XEN console request irq failed %i\n", err);
                return err;
diff -r 46bd7564125d -r 2d2414d6f938 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Tue Oct 11 12:02:59 2005
+++ b/tools/console/daemon/io.c Tue Oct 11 13:14:54 2005
@@ -25,6 +25,7 @@
 #include <xenctrl.h>
 #include <xs.h>
 #include <xen/linux/evtchn.h>
+#include <xen/io/console.h>
 
 #include <malloc.h>
 #include <stdlib.h>
@@ -62,24 +63,11 @@
        char *conspath;
        int ring_ref;
        int local_port;
-       char *page;
        int evtchn_fd;
+       struct xencons_interface *interface;
 };
 
 static struct domain *dom_head;
-
-struct ring_head
-{
-       u32 cons;
-       u32 prod;
-       char buf[0];
-} __attribute__((packed));
-
-#define PAGE_SIZE (getpagesize())
-#define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head))
-#define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE)
-#define XENCONS_FULL(ring) (((ring)->prod - (ring)->cons) == XENCONS_RING_SIZE)
-#define XENCONS_SPACE(ring) (XENCONS_RING_SIZE - ((ring)->prod - (ring)->cons))
 
 static void evtchn_notify(struct domain *dom)
 {
@@ -91,12 +79,12 @@
 static void buffer_append(struct domain *dom)
 {
        struct buffer *buffer = &dom->buffer;
-       struct ring_head *ring = (struct ring_head *)dom->page;
        size_t size;
-       u32 oldcons;
+       XENCONS_RING_IDX oldcons;
        int notify = 0;
-
-       while ((size = ring->prod - ring->cons) != 0) {
+       struct xencons_interface *intf = dom->interface;
+
+       while ((size = (intf->out_prod - intf->out_cons)) != 0) {
                notify = 1;
 
                if ((buffer->capacity - buffer->size) < size) {
@@ -108,12 +96,12 @@
                        }
                }
 
-               oldcons = ring->cons;
-               while (ring->cons < (oldcons + size)) {
-                       buffer->data[buffer->size] =
-                               ring->buf[XENCONS_IDX(ring->cons)];
+               oldcons = intf->out_cons;
+               while ((intf->out_cons - oldcons) < size) {
+                       buffer->data[buffer->size] = intf->out[
+                               MASK_XENCONS_IDX(intf->out_cons, intf->out)];
                        buffer->size++;
-                       ring->cons++;
+                       intf->out_cons++;
                }
 
                if (buffer->max_capacity &&
@@ -246,12 +234,13 @@
                goto out;
 
        if (ring_ref != dom->ring_ref) {
-               if (dom->page)
-                       munmap(dom->page, getpagesize());
-               dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(),
-                                                PROT_READ|PROT_WRITE,
-                                                (unsigned long)ring_ref);
-               if (dom->page == NULL) {
+               if (dom->interface != NULL)
+                       munmap(dom->interface, getpagesize());
+               dom->interface = xc_map_foreign_range(
+                       xc, dom->domid, getpagesize(),
+                       PROT_READ|PROT_WRITE,
+                       (unsigned long)ring_ref);
+               if (dom->interface == NULL) {
                        err = EINVAL;
                        goto out;
                }
@@ -334,7 +323,7 @@
 
        dom->ring_ref = -1;
        dom->local_port = -1;
-       dom->page = NULL;
+       dom->interface = NULL;
        dom->evtchn_fd = -1;
 
        if (!watch_domain(dom, true))
@@ -396,9 +385,9 @@
 {
        d->is_dead = true;
        watch_domain(d, false);
-       if (d->page)
-               munmap(d->page, getpagesize());
-       d->page = NULL;
+       if (d->interface != NULL)
+               munmap(d->interface, getpagesize());
+       d->interface = NULL;
        if (d->evtchn_fd != -1)
                close(d->evtchn_fd);
        d->evtchn_fd = -1;
@@ -426,13 +415,21 @@
 
 static void handle_tty_read(struct domain *dom)
 {
-       ssize_t len;
+       ssize_t len = 0;
        char msg[80];
-       struct ring_head *inring =
-               (struct ring_head *)(dom->page + PAGE_SIZE/2);
        int i;
-
-       len = read(dom->tty_fd, msg, MIN(XENCONS_SPACE(inring), sizeof(msg)));
+       struct xencons_interface *intf = dom->interface;
+       XENCONS_RING_IDX filled = intf->in_prod - intf->in_cons;
+
+       if (sizeof(intf->in) > filled)
+               len = sizeof(intf->in) - filled;
+       if (len > sizeof(msg))
+               len = sizeof(msg);
+
+       if (len == 0)
+               return;
+
+       len = read(dom->tty_fd, msg, len);
        if (len < 1) {
                close(dom->tty_fd);
                dom->tty_fd = -1;
@@ -444,8 +441,9 @@
                }
        } else if (domain_is_valid(dom->domid)) {
                for (i = 0; i < len; i++) {
-                       inring->buf[XENCONS_IDX(inring->prod)] = msg[i];
-                       inring->prod++;
+                       intf->in[MASK_XENCONS_IDX(intf->in_prod, intf->in)] =
+                               msg[i];
+                       intf->in_prod++;
                }
                evtchn_notify(dom);
        } else {
@@ -564,3 +562,13 @@
                }
        } while (ret > -1);
 }
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 46bd7564125d -r 2d2414d6f938 xen/include/public/io/console.h
--- /dev/null   Tue Oct 11 12:02:59 2005
+++ b/xen/include/public/io/console.h   Tue Oct 11 13:14:54 2005
@@ -0,0 +1,23 @@
+/******************************************************************************
+ * console.h
+ * 
+ * Console I/O interface for Xen guest OSes.
+ * 
+ * Copyright (c) 2005, Keir Fraser
+ */
+
+#ifndef __XEN_PUBLIC_IO_CONSOLE_H__
+#define __XEN_PUBLIC_IO_CONSOLE_H__
+
+typedef u32 XENCONS_RING_IDX;
+
+#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
+
+struct xencons_interface {
+    char in[1024];
+    char out[2048];
+    XENCONS_RING_IDX in_cons, in_prod;
+    XENCONS_RING_IDX out_cons, out_prod;
+};
+
+#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.