# 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
|