[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |