ia64/xen-unstable
changeset 7322:2d2414d6f938
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@xensource.com>
Make the ring buffers a powe-of-two in size.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Tue Oct 11 14:14:54 2005 +0100 (2005-10-11) |
parents | 46bd7564125d |
children | 959d33fbd660 |
files | linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c tools/console/daemon/io.c xen/include/public/io/console.h |
line diff
1.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Tue Oct 11 13:02:59 2005 +0100 1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Tue Oct 11 14:14:54 2005 +0100 1.3 @@ -20,69 +20,48 @@ 1.4 #include <linux/sched.h> 1.5 #include <linux/err.h> 1.6 #include "xencons_ring.h" 1.7 - 1.8 -struct ring_head 1.9 -{ 1.10 - u32 cons; 1.11 - u32 prod; 1.12 - char buf[0]; 1.13 -} __attribute__((packed)); 1.14 +#include <asm-xen/xen-public/io/console.h> 1.15 1.16 static int xencons_irq; 1.17 +static xencons_receiver_func *xencons_receiver; 1.18 1.19 -#define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head)) 1.20 -#define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE) 1.21 -#define XENCONS_FULL(ring) (((ring)->prod - (ring)->cons) == XENCONS_RING_SIZE) 1.22 - 1.23 -static inline struct ring_head *outring(void) 1.24 +static inline struct xencons_interface *xencons_interface(void) 1.25 { 1.26 return mfn_to_virt(xen_start_info->console_mfn); 1.27 } 1.28 1.29 -static inline struct ring_head *inring(void) 1.30 -{ 1.31 - return mfn_to_virt(xen_start_info->console_mfn) + PAGE_SIZE/2; 1.32 -} 1.33 - 1.34 - 1.35 -/* don't block - write as much as possible and return */ 1.36 -static int __xencons_ring_send( 1.37 - struct ring_head *ring, const char *data, unsigned len) 1.38 -{ 1.39 - int copied = 0; 1.40 - 1.41 - mb(); 1.42 - while (copied < len && !XENCONS_FULL(ring)) { 1.43 - ring->buf[XENCONS_IDX(ring->prod)] = data[copied]; 1.44 - ring->prod++; 1.45 - copied++; 1.46 - } 1.47 - mb(); 1.48 - 1.49 - return copied; 1.50 -} 1.51 - 1.52 int xencons_ring_send(const char *data, unsigned len) 1.53 { 1.54 - int sent = __xencons_ring_send(outring(), data, len); 1.55 + int sent = 0; 1.56 + struct xencons_interface *intf = xencons_interface(); 1.57 + 1.58 + while ((sent < len) && 1.59 + (intf->out_prod - intf->out_cons) < sizeof(intf->out)) { 1.60 + intf->out[MASK_XENCONS_IDX(intf->out_prod, intf->out)] = 1.61 + data[sent]; 1.62 + intf->out_prod++; 1.63 + sent++; 1.64 + } 1.65 + 1.66 /* Use evtchn: this is called early, before irq is set up. */ 1.67 notify_remote_via_evtchn(xen_start_info->console_evtchn); 1.68 + 1.69 return sent; 1.70 } 1.71 1.72 - 1.73 -static xencons_receiver_func *xencons_receiver; 1.74 - 1.75 static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs) 1.76 { 1.77 - struct ring_head *ring = inring(); 1.78 - while (ring->cons < ring->prod) { 1.79 - if (xencons_receiver != NULL) { 1.80 - xencons_receiver(ring->buf + XENCONS_IDX(ring->cons), 1.81 - 1, regs); 1.82 - } 1.83 - ring->cons++; 1.84 + struct xencons_interface *intf = xencons_interface(); 1.85 + 1.86 + while (intf->in_cons != intf->in_prod) { 1.87 + if (xencons_receiver != NULL) 1.88 + xencons_receiver( 1.89 + intf->in + MASK_XENCONS_IDX(intf->in_cons, 1.90 + intf->in), 1.91 + 1, regs); 1.92 + intf->in_cons++; 1.93 } 1.94 + 1.95 return IRQ_HANDLED; 1.96 } 1.97 1.98 @@ -96,7 +75,7 @@ int xencons_ring_init(void) 1.99 int err; 1.100 1.101 if (xencons_irq) 1.102 - unbind_evtchn_from_irqhandler(xencons_irq, inring()); 1.103 + unbind_evtchn_from_irqhandler(xencons_irq, NULL); 1.104 xencons_irq = 0; 1.105 1.106 if (!xen_start_info->console_evtchn) 1.107 @@ -104,7 +83,7 @@ int xencons_ring_init(void) 1.108 1.109 err = bind_evtchn_to_irqhandler( 1.110 xen_start_info->console_evtchn, 1.111 - handle_input, 0, "xencons", inring()); 1.112 + handle_input, 0, "xencons", NULL); 1.113 if (err <= 0) { 1.114 xprintk("XEN console request irq failed %i\n", err); 1.115 return err;
2.1 --- a/tools/console/daemon/io.c Tue Oct 11 13:02:59 2005 +0100 2.2 +++ b/tools/console/daemon/io.c Tue Oct 11 14:14:54 2005 +0100 2.3 @@ -25,6 +25,7 @@ 2.4 #include <xenctrl.h> 2.5 #include <xs.h> 2.6 #include <xen/linux/evtchn.h> 2.7 +#include <xen/io/console.h> 2.8 2.9 #include <malloc.h> 2.10 #include <stdlib.h> 2.11 @@ -62,25 +63,12 @@ struct domain 2.12 char *conspath; 2.13 int ring_ref; 2.14 int local_port; 2.15 - char *page; 2.16 int evtchn_fd; 2.17 + struct xencons_interface *interface; 2.18 }; 2.19 2.20 static struct domain *dom_head; 2.21 2.22 -struct ring_head 2.23 -{ 2.24 - u32 cons; 2.25 - u32 prod; 2.26 - char buf[0]; 2.27 -} __attribute__((packed)); 2.28 - 2.29 -#define PAGE_SIZE (getpagesize()) 2.30 -#define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head)) 2.31 -#define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE) 2.32 -#define XENCONS_FULL(ring) (((ring)->prod - (ring)->cons) == XENCONS_RING_SIZE) 2.33 -#define XENCONS_SPACE(ring) (XENCONS_RING_SIZE - ((ring)->prod - (ring)->cons)) 2.34 - 2.35 static void evtchn_notify(struct domain *dom) 2.36 { 2.37 struct ioctl_evtchn_notify notify; 2.38 @@ -91,12 +79,12 @@ static void evtchn_notify(struct domain 2.39 static void buffer_append(struct domain *dom) 2.40 { 2.41 struct buffer *buffer = &dom->buffer; 2.42 - struct ring_head *ring = (struct ring_head *)dom->page; 2.43 size_t size; 2.44 - u32 oldcons; 2.45 + XENCONS_RING_IDX oldcons; 2.46 int notify = 0; 2.47 + struct xencons_interface *intf = dom->interface; 2.48 2.49 - while ((size = ring->prod - ring->cons) != 0) { 2.50 + while ((size = (intf->out_prod - intf->out_cons)) != 0) { 2.51 notify = 1; 2.52 2.53 if ((buffer->capacity - buffer->size) < size) { 2.54 @@ -108,12 +96,12 @@ static void buffer_append(struct domain 2.55 } 2.56 } 2.57 2.58 - oldcons = ring->cons; 2.59 - while (ring->cons < (oldcons + size)) { 2.60 - buffer->data[buffer->size] = 2.61 - ring->buf[XENCONS_IDX(ring->cons)]; 2.62 + oldcons = intf->out_cons; 2.63 + while ((intf->out_cons - oldcons) < size) { 2.64 + buffer->data[buffer->size] = intf->out[ 2.65 + MASK_XENCONS_IDX(intf->out_cons, intf->out)]; 2.66 buffer->size++; 2.67 - ring->cons++; 2.68 + intf->out_cons++; 2.69 } 2.70 2.71 if (buffer->max_capacity && 2.72 @@ -246,12 +234,13 @@ static int domain_create_ring(struct dom 2.73 goto out; 2.74 2.75 if (ring_ref != dom->ring_ref) { 2.76 - if (dom->page) 2.77 - munmap(dom->page, getpagesize()); 2.78 - dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(), 2.79 - PROT_READ|PROT_WRITE, 2.80 - (unsigned long)ring_ref); 2.81 - if (dom->page == NULL) { 2.82 + if (dom->interface != NULL) 2.83 + munmap(dom->interface, getpagesize()); 2.84 + dom->interface = xc_map_foreign_range( 2.85 + xc, dom->domid, getpagesize(), 2.86 + PROT_READ|PROT_WRITE, 2.87 + (unsigned long)ring_ref); 2.88 + if (dom->interface == NULL) { 2.89 err = EINVAL; 2.90 goto out; 2.91 } 2.92 @@ -334,7 +323,7 @@ static struct domain *create_domain(int 2.93 2.94 dom->ring_ref = -1; 2.95 dom->local_port = -1; 2.96 - dom->page = NULL; 2.97 + dom->interface = NULL; 2.98 dom->evtchn_fd = -1; 2.99 2.100 if (!watch_domain(dom, true)) 2.101 @@ -396,9 +385,9 @@ static void shutdown_domain(struct domai 2.102 { 2.103 d->is_dead = true; 2.104 watch_domain(d, false); 2.105 - if (d->page) 2.106 - munmap(d->page, getpagesize()); 2.107 - d->page = NULL; 2.108 + if (d->interface != NULL) 2.109 + munmap(d->interface, getpagesize()); 2.110 + d->interface = NULL; 2.111 if (d->evtchn_fd != -1) 2.112 close(d->evtchn_fd); 2.113 d->evtchn_fd = -1; 2.114 @@ -426,13 +415,21 @@ void enum_domains(void) 2.115 2.116 static void handle_tty_read(struct domain *dom) 2.117 { 2.118 - ssize_t len; 2.119 + ssize_t len = 0; 2.120 char msg[80]; 2.121 - struct ring_head *inring = 2.122 - (struct ring_head *)(dom->page + PAGE_SIZE/2); 2.123 int i; 2.124 + struct xencons_interface *intf = dom->interface; 2.125 + XENCONS_RING_IDX filled = intf->in_prod - intf->in_cons; 2.126 2.127 - len = read(dom->tty_fd, msg, MIN(XENCONS_SPACE(inring), sizeof(msg))); 2.128 + if (sizeof(intf->in) > filled) 2.129 + len = sizeof(intf->in) - filled; 2.130 + if (len > sizeof(msg)) 2.131 + len = sizeof(msg); 2.132 + 2.133 + if (len == 0) 2.134 + return; 2.135 + 2.136 + len = read(dom->tty_fd, msg, len); 2.137 if (len < 1) { 2.138 close(dom->tty_fd); 2.139 dom->tty_fd = -1; 2.140 @@ -444,8 +441,9 @@ static void handle_tty_read(struct domai 2.141 } 2.142 } else if (domain_is_valid(dom->domid)) { 2.143 for (i = 0; i < len; i++) { 2.144 - inring->buf[XENCONS_IDX(inring->prod)] = msg[i]; 2.145 - inring->prod++; 2.146 + intf->in[MASK_XENCONS_IDX(intf->in_prod, intf->in)] = 2.147 + msg[i]; 2.148 + intf->in_prod++; 2.149 } 2.150 evtchn_notify(dom); 2.151 } else { 2.152 @@ -564,3 +562,13 @@ void handle_io(void) 2.153 } 2.154 } while (ret > -1); 2.155 } 2.156 + 2.157 +/* 2.158 + * Local variables: 2.159 + * c-file-style: "linux" 2.160 + * indent-tabs-mode: t 2.161 + * c-indent-level: 8 2.162 + * c-basic-offset: 8 2.163 + * tab-width: 8 2.164 + * End: 2.165 + */
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/xen/include/public/io/console.h Tue Oct 11 14:14:54 2005 +0100 3.3 @@ -0,0 +1,23 @@ 3.4 +/****************************************************************************** 3.5 + * console.h 3.6 + * 3.7 + * Console I/O interface for Xen guest OSes. 3.8 + * 3.9 + * Copyright (c) 2005, Keir Fraser 3.10 + */ 3.11 + 3.12 +#ifndef __XEN_PUBLIC_IO_CONSOLE_H__ 3.13 +#define __XEN_PUBLIC_IO_CONSOLE_H__ 3.14 + 3.15 +typedef u32 XENCONS_RING_IDX; 3.16 + 3.17 +#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1)) 3.18 + 3.19 +struct xencons_interface { 3.20 + char in[1024]; 3.21 + char out[2048]; 3.22 + XENCONS_RING_IDX in_cons, in_prod; 3.23 + XENCONS_RING_IDX out_cons, out_prod; 3.24 +}; 3.25 + 3.26 +#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */