ia64/xen-unstable

view extras/mini-os/console/xencons_ring.c @ 18811:390ef36eb596

Remove Xen-private definitions from kexec public header.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Nov 19 13:13:39 2008 +0000 (2008-11-19)
parents 5c38568d90df
children 11d8ca329b54
line source
1 #include <types.h>
2 #include <wait.h>
3 #include <mm.h>
4 #include <hypervisor.h>
5 #include <events.h>
6 #include <os.h>
7 #include <lib.h>
8 #include <xenbus.h>
9 #include <xen/io/console.h>
11 DECLARE_WAIT_QUEUE_HEAD(console_queue);
13 static inline struct xencons_interface *xencons_interface(void)
14 {
15 return mfn_to_virt(start_info.console.domU.mfn);
16 }
18 static inline void notify_daemon(void)
19 {
20 /* Use evtchn: this is called early, before irq is set up. */
21 notify_remote_via_evtchn(start_info.console.domU.evtchn);
22 }
24 int xencons_ring_send_no_notify(const char *data, unsigned len)
25 {
26 int sent = 0;
27 struct xencons_interface *intf = xencons_interface();
28 XENCONS_RING_IDX cons, prod;
29 cons = intf->out_cons;
30 prod = intf->out_prod;
31 mb();
32 BUG_ON((prod - cons) > sizeof(intf->out));
34 while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
35 intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
37 wmb();
38 intf->out_prod = prod;
40 return sent;
41 }
43 int xencons_ring_send(const char *data, unsigned len)
44 {
45 int sent;
46 sent = xencons_ring_send_no_notify(data, len);
47 notify_daemon();
49 return sent;
50 }
54 static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign)
55 {
56 #ifdef HAVE_LIBC
57 wake_up(&console_queue);
58 #else
59 struct xencons_interface *intf = xencons_interface();
60 XENCONS_RING_IDX cons, prod;
62 cons = intf->in_cons;
63 prod = intf->in_prod;
64 mb();
65 BUG_ON((prod - cons) > sizeof(intf->in));
67 while (cons != prod) {
68 xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs);
69 cons++;
70 }
72 mb();
73 intf->in_cons = cons;
75 notify_daemon();
77 xencons_tx();
78 #endif
79 }
81 #ifdef HAVE_LIBC
82 int xencons_ring_avail(void)
83 {
84 struct xencons_interface *intf = xencons_interface();
85 XENCONS_RING_IDX cons, prod;
87 cons = intf->in_cons;
88 prod = intf->in_prod;
89 mb();
90 BUG_ON((prod - cons) > sizeof(intf->in));
92 return prod - cons;
93 }
95 int xencons_ring_recv(char *data, unsigned len)
96 {
97 struct xencons_interface *intf = xencons_interface();
98 XENCONS_RING_IDX cons, prod;
99 unsigned filled = 0;
101 cons = intf->in_cons;
102 prod = intf->in_prod;
103 mb();
104 BUG_ON((prod - cons) > sizeof(intf->in));
106 while (filled < len && cons + filled != prod) {
107 data[filled] = *(intf->in + MASK_XENCONS_IDX(cons + filled, intf->in));
108 filled++;
109 }
111 mb();
112 intf->in_cons = cons + filled;
114 notify_daemon();
116 return filled;
117 }
118 #endif
120 int xencons_ring_init(void)
121 {
122 int err;
124 if (!start_info.console.domU.evtchn)
125 return 0;
127 err = bind_evtchn(start_info.console.domU.evtchn, handle_input,
128 NULL);
129 if (err <= 0) {
130 printk("XEN console request chn bind failed %i\n", err);
131 return err;
132 }
133 unmask_evtchn(start_info.console.domU.evtchn);
135 /* In case we have in-flight data after save/restore... */
136 notify_daemon();
138 return 0;
139 }
141 void xencons_resume(void)
142 {
143 (void)xencons_ring_init();
144 }