direct-io.hg

view extras/mini-os/xenbus/xenbus_comms.c @ 8693:491a8798945e

Remove shadow-translate Linux patches for now. We'll merge this stuff
in piecemeal.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sat Jan 28 12:09:45 2006 +0100 (2006-01-28)
parents 7557f0b4098c
children
line source
1 /******************************************************************************
2 * xenbus_comms.c
3 *
4 * Low level code to talks to Xen Store: ringbuffer and event channel.
5 *
6 * Copyright (C) 2005 Rusty Russell, IBM Corporation
7 *
8 * This file may be distributed separately from the Linux kernel, or
9 * incorporated into other software packages, subject to the following license:
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this source file (the "Software"), to deal in the Software without
13 * restriction, including without limitation the rights to use, copy, modify,
14 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
15 * and to permit persons to whom the Software is furnished to do so, subject to
16 * the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 * IN THE SOFTWARE.
28 */
29 #include <types.h>
30 #include <wait.h>
31 #include <mm.h>
32 #include <hypervisor.h>
33 #include <events.h>
34 #include <os.h>
35 #include <lib.h>
36 #include <xenbus.h>
37 #include "xenbus_comms.h"
39 static int xenbus_irq;
41 extern void xenbus_probe(void *);
42 extern int xenstored_ready;
44 DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
46 static inline struct xenstore_domain_interface *xenstore_domain_interface(void)
47 {
48 return mfn_to_virt(start_info.store_mfn);
49 }
51 static void wake_waiting(int port, struct pt_regs *regs)
52 {
53 wake_up(&xb_waitq);
54 }
56 static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
57 {
58 return ((prod - cons) <= XENSTORE_RING_SIZE);
59 }
61 static void *get_output_chunk(XENSTORE_RING_IDX cons,
62 XENSTORE_RING_IDX prod,
63 char *buf, uint32_t *len)
64 {
65 *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
66 if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
67 *len = XENSTORE_RING_SIZE - (prod - cons);
68 return buf + MASK_XENSTORE_IDX(prod);
69 }
71 static const void *get_input_chunk(XENSTORE_RING_IDX cons,
72 XENSTORE_RING_IDX prod,
73 const char *buf, uint32_t *len)
74 {
75 *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
76 if ((prod - cons) < *len)
77 *len = prod - cons;
78 return buf + MASK_XENSTORE_IDX(cons);
79 }
81 int xb_write(const void *data, unsigned len)
82 {
83 struct xenstore_domain_interface *intf = xenstore_domain_interface();
84 XENSTORE_RING_IDX cons, prod;
86 while (len != 0) {
87 void *dst;
88 unsigned int avail;
90 wait_event(xb_waitq, (intf->req_prod - intf->req_cons) !=
91 XENSTORE_RING_SIZE);
93 /* Read indexes, then verify. */
94 cons = intf->req_cons;
95 prod = intf->req_prod;
96 mb();
97 if (!check_indexes(cons, prod))
98 return -EIO;
100 dst = get_output_chunk(cons, prod, intf->req, &avail);
101 if (avail == 0)
102 continue;
103 if (avail > len)
104 avail = len;
106 memcpy(dst, data, avail);
107 data = (void*) ( (unsigned long)data + avail );
108 len -= avail;
110 /* Other side must not see new header until data is there. */
111 wmb();
112 intf->req_prod += avail;
114 /* This implies mb() before other side sees interrupt. */
115 notify_remote_via_evtchn(start_info.store_evtchn);
116 }
118 return 0;
119 }
121 int xb_read(void *data, unsigned len)
122 {
123 struct xenstore_domain_interface *intf = xenstore_domain_interface();
124 XENSTORE_RING_IDX cons, prod;
126 while (len != 0) {
127 unsigned int avail;
128 const char *src;
130 wait_event(xb_waitq,
131 intf->rsp_cons != intf->rsp_prod);
133 /* Read indexes, then verify. */
134 cons = intf->rsp_cons;
135 prod = intf->rsp_prod;
136 mb();
137 if (!check_indexes(cons, prod))
138 return -EIO;
140 src = get_input_chunk(cons, prod, intf->rsp, &avail);
141 if (avail == 0)
142 continue;
143 if (avail > len)
144 avail = len;
146 /* We must read header before we read data. */
147 rmb();
149 memcpy(data, src, avail);
150 data = (void*) ( (unsigned long)data + avail );
151 len -= avail;
153 /* Other side must not see free space until we've copied out */
154 mb();
155 intf->rsp_cons += avail;
157 printk("Finished read of %i bytes (%i to go)\n", avail, len);
159 /* Implies mb(): they will see new header. */
160 notify_remote_via_evtchn(start_info.store_evtchn);
161 }
163 return 0;
164 }
166 /* Set up interrupt handler off store event channel. */
167 int xb_init_comms(void)
168 {
169 int err;
171 if (xenbus_irq)
172 unbind_evtchn(xenbus_irq);
174 err = bind_evtchn(
175 start_info.store_evtchn, wake_waiting);
176 if (err <= 0) {
177 printk("XENBUS request irq failed %i\n", err);
178 return err;
179 }
181 xenbus_irq = err;
183 return 0;
184 }