xenbus_probe.c revision 1.1 1 1.1 bouyer /******************************************************************************
2 1.1 bouyer * Talks to Xen Store to figure out what devices we have.
3 1.1 bouyer *
4 1.1 bouyer * Copyright (C) 2005 Rusty Russell, IBM Corporation
5 1.1 bouyer * Copyright (C) 2005 Mike Wray, Hewlett-Packard
6 1.1 bouyer * Copyright (C) 2005 XenSource Ltd
7 1.1 bouyer *
8 1.1 bouyer * This file may be distributed separately from the Linux kernel, or
9 1.1 bouyer * incorporated into other software packages, subject to the following license:
10 1.1 bouyer *
11 1.1 bouyer * Permission is hereby granted, free of charge, to any person obtaining a copy
12 1.1 bouyer * of this source file (the "Software"), to deal in the Software without
13 1.1 bouyer * restriction, including without limitation the rights to use, copy, modify,
14 1.1 bouyer * merge, publish, distribute, sublicense, and/or sell copies of the Software,
15 1.1 bouyer * and to permit persons to whom the Software is furnished to do so, subject to
16 1.1 bouyer * the following conditions:
17 1.1 bouyer *
18 1.1 bouyer * The above copyright notice and this permission notice shall be included in
19 1.1 bouyer * all copies or substantial portions of the Software.
20 1.1 bouyer *
21 1.1 bouyer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 1.1 bouyer * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 1.1 bouyer * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 1.1 bouyer * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 1.1 bouyer * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 1.1 bouyer * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 1.1 bouyer * IN THE SOFTWARE.
28 1.1 bouyer */
29 1.1 bouyer
30 1.1 bouyer #if 0
31 1.1 bouyer #define DPRINTK(fmt, args...) \
32 1.1 bouyer printk("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
33 1.1 bouyer #else
34 1.1 bouyer #define DPRINTK(fmt, args...) ((void)0)
35 1.1 bouyer #endif
36 1.1 bouyer
37 1.1 bouyer #include <linux/kernel.h>
38 1.1 bouyer #include <linux/err.h>
39 1.1 bouyer #include <linux/string.h>
40 1.1 bouyer #include <linux/ctype.h>
41 1.1 bouyer #include <linux/fcntl.h>
42 1.1 bouyer #include <linux/mm.h>
43 1.1 bouyer #include <linux/notifier.h>
44 1.1 bouyer #include <linux/kthread.h>
45 1.1 bouyer
46 1.1 bouyer #include <asm/io.h>
47 1.1 bouyer #include <asm/page.h>
48 1.1 bouyer #include <asm/pgtable.h>
49 1.1 bouyer #include <asm/hypervisor.h>
50 1.1 bouyer #include <asm-xen/xenbus.h>
51 1.1 bouyer #include <asm-xen/xen_proc.h>
52 1.1 bouyer #include <asm-xen/balloon.h>
53 1.1 bouyer #include <asm-xen/evtchn.h>
54 1.1 bouyer #include <asm-xen/linux-public/evtchn.h>
55 1.1 bouyer
56 1.1 bouyer #include "xenbus_comms.h"
57 1.1 bouyer
58 1.1 bouyer extern struct semaphore xenwatch_mutex;
59 1.1 bouyer
60 1.1 bouyer #define streq(a, b) (strcmp((a), (b)) == 0)
61 1.1 bouyer
62 1.1 bouyer static char *kasprintf(const char *fmt, ...);
63 1.1 bouyer
64 1.1 bouyer static struct notifier_block *xenstore_chain;
65 1.1 bouyer
66 1.1 bouyer /* If something in array of ids matches this device, return it. */
67 1.1 bouyer static const struct xenbus_device_id *
68 1.1 bouyer match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev)
69 1.1 bouyer {
70 1.1 bouyer for (; !streq(arr->devicetype, ""); arr++) {
71 1.1 bouyer if (streq(arr->devicetype, dev->devicetype))
72 1.1 bouyer return arr;
73 1.1 bouyer }
74 1.1 bouyer return NULL;
75 1.1 bouyer }
76 1.1 bouyer
77 1.1 bouyer static int xenbus_match(struct device *_dev, struct device_driver *_drv)
78 1.1 bouyer {
79 1.1 bouyer struct xenbus_driver *drv = to_xenbus_driver(_drv);
80 1.1 bouyer
81 1.1 bouyer if (!drv->ids)
82 1.1 bouyer return 0;
83 1.1 bouyer
84 1.1 bouyer return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
85 1.1 bouyer }
86 1.1 bouyer
87 1.1 bouyer struct xen_bus_type
88 1.1 bouyer {
89 1.1 bouyer char *root;
90 1.1 bouyer unsigned int levels;
91 1.1 bouyer int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
92 1.1 bouyer int (*probe)(const char *type, const char *dir);
93 1.1 bouyer struct bus_type bus;
94 1.1 bouyer struct device dev;
95 1.1 bouyer };
96 1.1 bouyer
97 1.1 bouyer
98 1.1 bouyer /* device/<type>/<id> => <type>-<id> */
99 1.1 bouyer static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
100 1.1 bouyer {
101 1.1 bouyer nodename = strchr(nodename, '/');
102 1.1 bouyer if (!nodename || strlen(nodename + 1) >= BUS_ID_SIZE) {
103 1.1 bouyer printk(KERN_WARNING "XENBUS: bad frontend %s\n", nodename);
104 1.1 bouyer return -EINVAL;
105 1.1 bouyer }
106 1.1 bouyer
107 1.1 bouyer strlcpy(bus_id, nodename + 1, BUS_ID_SIZE);
108 1.1 bouyer if (!strchr(bus_id, '/')) {
109 1.1 bouyer printk(KERN_WARNING "XENBUS: bus_id %s no slash\n", bus_id);
110 1.1 bouyer return -EINVAL;
111 1.1 bouyer }
112 1.1 bouyer *strchr(bus_id, '/') = '-';
113 1.1 bouyer return 0;
114 1.1 bouyer }
115 1.1 bouyer
116 1.1 bouyer
117 1.1 bouyer static int read_otherend_details(struct xenbus_device *xendev,
118 1.1 bouyer char *id_node, char *path_node)
119 1.1 bouyer {
120 1.1 bouyer int err = xenbus_gather(NULL, xendev->nodename,
121 1.1 bouyer id_node, "%i", &xendev->otherend_id,
122 1.1 bouyer path_node, NULL, &xendev->otherend,
123 1.1 bouyer NULL);
124 1.1 bouyer if (err) {
125 1.1 bouyer xenbus_dev_fatal(xendev, err,
126 1.1 bouyer "reading other end details from %s",
127 1.1 bouyer xendev->nodename);
128 1.1 bouyer return err;
129 1.1 bouyer }
130 1.1 bouyer if (strlen(xendev->otherend) == 0 ||
131 1.1 bouyer !xenbus_exists(NULL, xendev->otherend, "")) {
132 1.1 bouyer xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
133 1.1 bouyer xendev->nodename);
134 1.1 bouyer kfree(xendev->otherend);
135 1.1 bouyer xendev->otherend = NULL;
136 1.1 bouyer return -ENOENT;
137 1.1 bouyer }
138 1.1 bouyer
139 1.1 bouyer return 0;
140 1.1 bouyer }
141 1.1 bouyer
142 1.1 bouyer
143 1.1 bouyer static int read_backend_details(struct xenbus_device *xendev)
144 1.1 bouyer {
145 1.1 bouyer return read_otherend_details(xendev, "backend-id", "backend");
146 1.1 bouyer }
147 1.1 bouyer
148 1.1 bouyer
149 1.1 bouyer static int read_frontend_details(struct xenbus_device *xendev)
150 1.1 bouyer {
151 1.1 bouyer return read_otherend_details(xendev, "frontend-id", "frontend");
152 1.1 bouyer }
153 1.1 bouyer
154 1.1 bouyer
155 1.1 bouyer static void free_otherend_details(struct xenbus_device *dev)
156 1.1 bouyer {
157 1.1 bouyer kfree(dev->otherend);
158 1.1 bouyer dev->otherend = NULL;
159 1.1 bouyer }
160 1.1 bouyer
161 1.1 bouyer
162 1.1 bouyer static void free_otherend_watch(struct xenbus_device *dev)
163 1.1 bouyer {
164 1.1 bouyer if (dev->otherend_watch.node) {
165 1.1 bouyer unregister_xenbus_watch(&dev->otherend_watch);
166 1.1 bouyer kfree(dev->otherend_watch.node);
167 1.1 bouyer dev->otherend_watch.node = NULL;
168 1.1 bouyer }
169 1.1 bouyer }
170 1.1 bouyer
171 1.1 bouyer
172 1.1 bouyer /* Bus type for frontend drivers. */
173 1.1 bouyer static int xenbus_probe_frontend(const char *type, const char *name);
174 1.1 bouyer static struct xen_bus_type xenbus_frontend = {
175 1.1 bouyer .root = "device",
176 1.1 bouyer .levels = 2, /* device/type/<id> */
177 1.1 bouyer .get_bus_id = frontend_bus_id,
178 1.1 bouyer .probe = xenbus_probe_frontend,
179 1.1 bouyer .bus = {
180 1.1 bouyer .name = "xen",
181 1.1 bouyer .match = xenbus_match,
182 1.1 bouyer },
183 1.1 bouyer .dev = {
184 1.1 bouyer .bus_id = "xen",
185 1.1 bouyer },
186 1.1 bouyer };
187 1.1 bouyer
188 1.1 bouyer /* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */
189 1.1 bouyer static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
190 1.1 bouyer {
191 1.1 bouyer int domid, err;
192 1.1 bouyer const char *devid, *type, *frontend;
193 1.1 bouyer unsigned int typelen;
194 1.1 bouyer
195 1.1 bouyer type = strchr(nodename, '/');
196 1.1 bouyer if (!type)
197 1.1 bouyer return -EINVAL;
198 1.1 bouyer type++;
199 1.1 bouyer typelen = strcspn(type, "/");
200 1.1 bouyer if (!typelen || type[typelen] != '/')
201 1.1 bouyer return -EINVAL;
202 1.1 bouyer
203 1.1 bouyer devid = strrchr(nodename, '/') + 1;
204 1.1 bouyer
205 1.1 bouyer err = xenbus_gather(NULL, nodename, "frontend-id", "%i", &domid,
206 1.1 bouyer "frontend", NULL, &frontend,
207 1.1 bouyer NULL);
208 1.1 bouyer if (err)
209 1.1 bouyer return err;
210 1.1 bouyer if (strlen(frontend) == 0)
211 1.1 bouyer err = -ERANGE;
212 1.1 bouyer
213 1.1 bouyer if (!err && !xenbus_exists(NULL, frontend, ""))
214 1.1 bouyer err = -ENOENT;
215 1.1 bouyer
216 1.1 bouyer if (err) {
217 1.1 bouyer kfree(frontend);
218 1.1 bouyer return err;
219 1.1 bouyer }
220 1.1 bouyer
221 1.1 bouyer if (snprintf(bus_id, BUS_ID_SIZE,
222 1.1 bouyer "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
223 1.1 bouyer return -ENOSPC;
224 1.1 bouyer return 0;
225 1.1 bouyer }
226 1.1 bouyer
227 1.1 bouyer static int xenbus_hotplug_backend(struct device *dev, char **envp,
228 1.1 bouyer int num_envp, char *buffer, int buffer_size)
229 1.1 bouyer {
230 1.1 bouyer struct xenbus_device *xdev;
231 1.1 bouyer struct xenbus_driver *drv = NULL;
232 1.1 bouyer int i = 0;
233 1.1 bouyer int length = 0;
234 1.1 bouyer char *basepath_end;
235 1.1 bouyer char *frontend_id;
236 1.1 bouyer
237 1.1 bouyer DPRINTK("");
238 1.1 bouyer
239 1.1 bouyer if (dev == NULL)
240 1.1 bouyer return -ENODEV;
241 1.1 bouyer
242 1.1 bouyer xdev = to_xenbus_device(dev);
243 1.1 bouyer if (xdev == NULL)
244 1.1 bouyer return -ENODEV;
245 1.1 bouyer
246 1.1 bouyer if (dev->driver)
247 1.1 bouyer drv = to_xenbus_driver(dev->driver);
248 1.1 bouyer
249 1.1 bouyer /* stuff we want to pass to /sbin/hotplug */
250 1.1 bouyer add_hotplug_env_var(envp, num_envp, &i,
251 1.1 bouyer buffer, buffer_size, &length,
252 1.1 bouyer "XENBUS_TYPE=%s", xdev->devicetype);
253 1.1 bouyer
254 1.1 bouyer add_hotplug_env_var(envp, num_envp, &i,
255 1.1 bouyer buffer, buffer_size, &length,
256 1.1 bouyer "XENBUS_PATH=%s", xdev->nodename);
257 1.1 bouyer
258 1.1 bouyer add_hotplug_env_var(envp, num_envp, &i,
259 1.1 bouyer buffer, buffer_size, &length,
260 1.1 bouyer "XENBUS_BASE_PATH=%s", xdev->nodename);
261 1.1 bouyer
262 1.1 bouyer basepath_end = strrchr(envp[i - 1], '/');
263 1.1 bouyer length -= strlen(basepath_end);
264 1.1 bouyer *basepath_end = '\0';
265 1.1 bouyer basepath_end = strrchr(envp[i - 1], '/');
266 1.1 bouyer length -= strlen(basepath_end);
267 1.1 bouyer *basepath_end = '\0';
268 1.1 bouyer
269 1.1 bouyer basepath_end++;
270 1.1 bouyer frontend_id = kmalloc(strlen(basepath_end) + 1, GFP_KERNEL);
271 1.1 bouyer strcpy(frontend_id, basepath_end);
272 1.1 bouyer add_hotplug_env_var(envp, num_envp, &i,
273 1.1 bouyer buffer, buffer_size, &length,
274 1.1 bouyer "XENBUS_FRONTEND_ID=%s", frontend_id);
275 1.1 bouyer kfree(frontend_id);
276 1.1 bouyer
277 1.1 bouyer /* terminate, set to next free slot, shrink available space */
278 1.1 bouyer envp[i] = NULL;
279 1.1 bouyer envp = &envp[i];
280 1.1 bouyer num_envp -= i;
281 1.1 bouyer buffer = &buffer[length];
282 1.1 bouyer buffer_size -= length;
283 1.1 bouyer
284 1.1 bouyer if (drv && drv->hotplug)
285 1.1 bouyer return drv->hotplug(xdev, envp, num_envp, buffer,
286 1.1 bouyer buffer_size);
287 1.1 bouyer
288 1.1 bouyer return 0;
289 1.1 bouyer }
290 1.1 bouyer
291 1.1 bouyer static int xenbus_probe_backend(const char *type, const char *domid);
292 1.1 bouyer static struct xen_bus_type xenbus_backend = {
293 1.1 bouyer .root = "backend",
294 1.1 bouyer .levels = 3, /* backend/type/<frontend>/<id> */
295 1.1 bouyer .get_bus_id = backend_bus_id,
296 1.1 bouyer .probe = xenbus_probe_backend,
297 1.1 bouyer .bus = {
298 1.1 bouyer .name = "xen-backend",
299 1.1 bouyer .match = xenbus_match,
300 1.1 bouyer .hotplug = xenbus_hotplug_backend,
301 1.1 bouyer },
302 1.1 bouyer .dev = {
303 1.1 bouyer .bus_id = "xen-backend",
304 1.1 bouyer },
305 1.1 bouyer };
306 1.1 bouyer
307 1.1 bouyer
308 1.1 bouyer static void otherend_changed(struct xenbus_watch *watch,
309 1.1 bouyer const char **vec, unsigned int len)
310 1.1 bouyer {
311 1.1 bouyer struct xenbus_device *dev =
312 1.1 bouyer container_of(watch, struct xenbus_device, otherend_watch);
313 1.1 bouyer struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
314 1.1 bouyer XenbusState state;
315 1.1 bouyer
316 1.1 bouyer /* Protect us against watches firing on old details when the otherend
317 1.1 bouyer details change, say immediately after a resume. */
318 1.1 bouyer if (!dev->otherend ||
319 1.1 bouyer strncmp(dev->otherend, vec[XS_WATCH_PATH],
320 1.1 bouyer strlen(dev->otherend))) {
321 1.1 bouyer DPRINTK("Ignoring watch at %s", vec[XS_WATCH_PATH]);
322 1.1 bouyer return;
323 1.1 bouyer }
324 1.1 bouyer
325 1.1 bouyer state = xenbus_read_driver_state(dev->otherend);
326 1.1 bouyer
327 1.1 bouyer DPRINTK("state is %d, %s, %s",
328 1.1 bouyer state, dev->otherend_watch.node, vec[XS_WATCH_PATH]);
329 1.1 bouyer if (drv->otherend_changed)
330 1.1 bouyer drv->otherend_changed(dev, state);
331 1.1 bouyer }
332 1.1 bouyer
333 1.1 bouyer
334 1.1 bouyer static int talk_to_otherend(struct xenbus_device *dev)
335 1.1 bouyer {
336 1.1 bouyer struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
337 1.1 bouyer int err;
338 1.1 bouyer
339 1.1 bouyer free_otherend_watch(dev);
340 1.1 bouyer free_otherend_details(dev);
341 1.1 bouyer
342 1.1 bouyer err = drv->read_otherend_details(dev);
343 1.1 bouyer if (err)
344 1.1 bouyer return err;
345 1.1 bouyer
346 1.1 bouyer return xenbus_watch_path2(dev, dev->otherend, "state",
347 1.1 bouyer &dev->otherend_watch, otherend_changed);
348 1.1 bouyer }
349 1.1 bouyer
350 1.1 bouyer
351 1.1 bouyer static int xenbus_dev_probe(struct device *_dev)
352 1.1 bouyer {
353 1.1 bouyer struct xenbus_device *dev = to_xenbus_device(_dev);
354 1.1 bouyer struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
355 1.1 bouyer const struct xenbus_device_id *id;
356 1.1 bouyer int err;
357 1.1 bouyer
358 1.1 bouyer DPRINTK("");
359 1.1 bouyer
360 1.1 bouyer err = talk_to_otherend(dev);
361 1.1 bouyer if (err) {
362 1.1 bouyer printk(KERN_WARNING
363 1.1 bouyer "xenbus_probe: talk_to_otherend on %s failed.\n",
364 1.1 bouyer dev->nodename);
365 1.1 bouyer return err;
366 1.1 bouyer }
367 1.1 bouyer
368 1.1 bouyer if (!drv->probe) {
369 1.1 bouyer err = -ENODEV;
370 1.1 bouyer goto fail;
371 1.1 bouyer }
372 1.1 bouyer
373 1.1 bouyer id = match_device(drv->ids, dev);
374 1.1 bouyer if (!id) {
375 1.1 bouyer err = -ENODEV;
376 1.1 bouyer goto fail;
377 1.1 bouyer }
378 1.1 bouyer
379 1.1 bouyer err = drv->probe(dev, id);
380 1.1 bouyer if (err)
381 1.1 bouyer goto fail;
382 1.1 bouyer
383 1.1 bouyer return 0;
384 1.1 bouyer fail:
385 1.1 bouyer xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
386 1.1 bouyer xenbus_switch_state(dev, NULL, XenbusStateClosed);
387 1.1 bouyer return -ENODEV;
388 1.1 bouyer
389 1.1 bouyer }
390 1.1 bouyer
391 1.1 bouyer static int xenbus_dev_remove(struct device *_dev)
392 1.1 bouyer {
393 1.1 bouyer struct xenbus_device *dev = to_xenbus_device(_dev);
394 1.1 bouyer struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
395 1.1 bouyer
396 1.1 bouyer DPRINTK("");
397 1.1 bouyer
398 1.1 bouyer free_otherend_watch(dev);
399 1.1 bouyer free_otherend_details(dev);
400 1.1 bouyer
401 1.1 bouyer if (drv->remove)
402 1.1 bouyer drv->remove(dev);
403 1.1 bouyer
404 1.1 bouyer xenbus_switch_state(dev, NULL, XenbusStateClosed);
405 1.1 bouyer return 0;
406 1.1 bouyer }
407 1.1 bouyer
408 1.1 bouyer static int xenbus_register_driver_common(struct xenbus_driver *drv,
409 1.1 bouyer struct xen_bus_type *bus)
410 1.1 bouyer {
411 1.1 bouyer int ret;
412 1.1 bouyer
413 1.1 bouyer drv->driver.name = drv->name;
414 1.1 bouyer drv->driver.bus = &bus->bus;
415 1.1 bouyer drv->driver.owner = drv->owner;
416 1.1 bouyer drv->driver.probe = xenbus_dev_probe;
417 1.1 bouyer drv->driver.remove = xenbus_dev_remove;
418 1.1 bouyer
419 1.1 bouyer down(&xenwatch_mutex);
420 1.1 bouyer ret = driver_register(&drv->driver);
421 1.1 bouyer up(&xenwatch_mutex);
422 1.1 bouyer return ret;
423 1.1 bouyer }
424 1.1 bouyer
425 1.1 bouyer int xenbus_register_frontend(struct xenbus_driver *drv)
426 1.1 bouyer {
427 1.1 bouyer drv->read_otherend_details = read_backend_details;
428 1.1 bouyer
429 1.1 bouyer return xenbus_register_driver_common(drv, &xenbus_frontend);
430 1.1 bouyer }
431 1.1 bouyer EXPORT_SYMBOL(xenbus_register_frontend);
432 1.1 bouyer
433 1.1 bouyer int xenbus_register_backend(struct xenbus_driver *drv)
434 1.1 bouyer {
435 1.1 bouyer drv->read_otherend_details = read_frontend_details;
436 1.1 bouyer
437 1.1 bouyer return xenbus_register_driver_common(drv, &xenbus_backend);
438 1.1 bouyer }
439 1.1 bouyer EXPORT_SYMBOL(xenbus_register_backend);
440 1.1 bouyer
441 1.1 bouyer void xenbus_unregister_driver(struct xenbus_driver *drv)
442 1.1 bouyer {
443 1.1 bouyer driver_unregister(&drv->driver);
444 1.1 bouyer }
445 1.1 bouyer EXPORT_SYMBOL(xenbus_unregister_driver);
446 1.1 bouyer
447 1.1 bouyer struct xb_find_info
448 1.1 bouyer {
449 1.1 bouyer struct xenbus_device *dev;
450 1.1 bouyer const char *nodename;
451 1.1 bouyer };
452 1.1 bouyer
453 1.1 bouyer static int cmp_dev(struct device *dev, void *data)
454 1.1 bouyer {
455 1.1 bouyer struct xenbus_device *xendev = to_xenbus_device(dev);
456 1.1 bouyer struct xb_find_info *info = data;
457 1.1 bouyer
458 1.1 bouyer if (streq(xendev->nodename, info->nodename)) {
459 1.1 bouyer info->dev = xendev;
460 1.1 bouyer get_device(dev);
461 1.1 bouyer return 1;
462 1.1 bouyer }
463 1.1 bouyer return 0;
464 1.1 bouyer }
465 1.1 bouyer
466 1.1 bouyer struct xenbus_device *xenbus_device_find(const char *nodename,
467 1.1 bouyer struct bus_type *bus)
468 1.1 bouyer {
469 1.1 bouyer struct xb_find_info info = { .dev = NULL, .nodename = nodename };
470 1.1 bouyer
471 1.1 bouyer bus_for_each_dev(bus, NULL, &info, cmp_dev);
472 1.1 bouyer return info.dev;
473 1.1 bouyer }
474 1.1 bouyer
475 1.1 bouyer static int cleanup_dev(struct device *dev, void *data)
476 1.1 bouyer {
477 1.1 bouyer struct xenbus_device *xendev = to_xenbus_device(dev);
478 1.1 bouyer struct xb_find_info *info = data;
479 1.1 bouyer int len = strlen(info->nodename);
480 1.1 bouyer
481 1.1 bouyer DPRINTK("%s", info->nodename);
482 1.1 bouyer
483 1.1 bouyer if (!strncmp(xendev->nodename, info->nodename, len)) {
484 1.1 bouyer info->dev = xendev;
485 1.1 bouyer get_device(dev);
486 1.1 bouyer return 1;
487 1.1 bouyer }
488 1.1 bouyer return 0;
489 1.1 bouyer }
490 1.1 bouyer
491 1.1 bouyer static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
492 1.1 bouyer {
493 1.1 bouyer struct xb_find_info info = { .nodename = path };
494 1.1 bouyer
495 1.1 bouyer do {
496 1.1 bouyer info.dev = NULL;
497 1.1 bouyer bus_for_each_dev(bus, NULL, &info, cleanup_dev);
498 1.1 bouyer if (info.dev) {
499 1.1 bouyer device_unregister(&info.dev->dev);
500 1.1 bouyer put_device(&info.dev->dev);
501 1.1 bouyer }
502 1.1 bouyer } while (info.dev);
503 1.1 bouyer }
504 1.1 bouyer
505 1.1 bouyer static void xenbus_dev_free(struct xenbus_device *xendev)
506 1.1 bouyer {
507 1.1 bouyer kfree(xendev);
508 1.1 bouyer }
509 1.1 bouyer
510 1.1 bouyer static void xenbus_dev_release(struct device *dev)
511 1.1 bouyer {
512 1.1 bouyer if (dev) {
513 1.1 bouyer xenbus_dev_free(to_xenbus_device(dev));
514 1.1 bouyer }
515 1.1 bouyer }
516 1.1 bouyer
517 1.1 bouyer /* Simplified asprintf. */
518 1.1 bouyer static char *kasprintf(const char *fmt, ...)
519 1.1 bouyer {
520 1.1 bouyer va_list ap;
521 1.1 bouyer unsigned int len;
522 1.1 bouyer char *p, dummy[1];
523 1.1 bouyer
524 1.1 bouyer va_start(ap, fmt);
525 1.1 bouyer /* FIXME: vsnprintf has a bug, NULL should work */
526 1.1 bouyer len = vsnprintf(dummy, 0, fmt, ap);
527 1.1 bouyer va_end(ap);
528 1.1 bouyer
529 1.1 bouyer p = kmalloc(len + 1, GFP_KERNEL);
530 1.1 bouyer if (!p)
531 1.1 bouyer return NULL;
532 1.1 bouyer va_start(ap, fmt);
533 1.1 bouyer vsprintf(p, fmt, ap);
534 1.1 bouyer va_end(ap);
535 1.1 bouyer return p;
536 1.1 bouyer }
537 1.1 bouyer
538 1.1 bouyer static ssize_t xendev_show_nodename(struct device *dev, char *buf)
539 1.1 bouyer {
540 1.1 bouyer return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
541 1.1 bouyer }
542 1.1 bouyer DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
543 1.1 bouyer
544 1.1 bouyer static ssize_t xendev_show_devtype(struct device *dev, char *buf)
545 1.1 bouyer {
546 1.1 bouyer return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
547 1.1 bouyer }
548 1.1 bouyer DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
549 1.1 bouyer
550 1.1 bouyer
551 1.1 bouyer static int xenbus_probe_node(struct xen_bus_type *bus,
552 1.1 bouyer const char *type,
553 1.1 bouyer const char *nodename)
554 1.1 bouyer {
555 1.1 bouyer #define CHECK_FAIL \
556 1.1 bouyer do { \
557 1.1 bouyer if (err) \
558 1.1 bouyer goto fail; \
559 1.1 bouyer } \
560 1.1 bouyer while (0) \
561 1.1 bouyer
562 1.1 bouyer
563 1.1 bouyer int err;
564 1.1 bouyer struct xenbus_device *xendev;
565 1.1 bouyer size_t stringlen;
566 1.1 bouyer char *tmpstring;
567 1.1 bouyer
568 1.1 bouyer XenbusState state = xenbus_read_driver_state(nodename);
569 1.1 bouyer
570 1.1 bouyer if (state != XenbusStateInitialising) {
571 1.1 bouyer /* Device is not new, so ignore it. This can happen if a
572 1.1 bouyer device is going away after switching to Closed. */
573 1.1 bouyer return 0;
574 1.1 bouyer }
575 1.1 bouyer
576 1.1 bouyer stringlen = strlen(nodename) + 1 + strlen(type) + 1;
577 1.1 bouyer xendev = kmalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
578 1.1 bouyer if (!xendev)
579 1.1 bouyer return -ENOMEM;
580 1.1 bouyer memset(xendev, 0, sizeof(*xendev));
581 1.1 bouyer
582 1.1 bouyer /* Copy the strings into the extra space. */
583 1.1 bouyer
584 1.1 bouyer tmpstring = (char *)(xendev + 1);
585 1.1 bouyer strcpy(tmpstring, nodename);
586 1.1 bouyer xendev->nodename = tmpstring;
587 1.1 bouyer
588 1.1 bouyer tmpstring += strlen(tmpstring) + 1;
589 1.1 bouyer strcpy(tmpstring, type);
590 1.1 bouyer xendev->devicetype = tmpstring;
591 1.1 bouyer
592 1.1 bouyer xendev->dev.parent = &bus->dev;
593 1.1 bouyer xendev->dev.bus = &bus->bus;
594 1.1 bouyer xendev->dev.release = xenbus_dev_release;
595 1.1 bouyer
596 1.1 bouyer err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
597 1.1 bouyer CHECK_FAIL;
598 1.1 bouyer
599 1.1 bouyer /* Register with generic device framework. */
600 1.1 bouyer err = device_register(&xendev->dev);
601 1.1 bouyer CHECK_FAIL;
602 1.1 bouyer
603 1.1 bouyer device_create_file(&xendev->dev, &dev_attr_nodename);
604 1.1 bouyer device_create_file(&xendev->dev, &dev_attr_devtype);
605 1.1 bouyer
606 1.1 bouyer return 0;
607 1.1 bouyer
608 1.1 bouyer #undef CHECK_FAIL
609 1.1 bouyer
610 1.1 bouyer fail:
611 1.1 bouyer xenbus_dev_free(xendev);
612 1.1 bouyer return err;
613 1.1 bouyer }
614 1.1 bouyer
615 1.1 bouyer /* device/<typename>/<name> */
616 1.1 bouyer static int xenbus_probe_frontend(const char *type, const char *name)
617 1.1 bouyer {
618 1.1 bouyer char *nodename;
619 1.1 bouyer int err;
620 1.1 bouyer
621 1.1 bouyer nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name);
622 1.1 bouyer if (!nodename)
623 1.1 bouyer return -ENOMEM;
624 1.1 bouyer
625 1.1 bouyer DPRINTK("%s", nodename);
626 1.1 bouyer
627 1.1 bouyer err = xenbus_probe_node(&xenbus_frontend, type, nodename);
628 1.1 bouyer kfree(nodename);
629 1.1 bouyer return err;
630 1.1 bouyer }
631 1.1 bouyer
632 1.1 bouyer /* backend/<typename>/<frontend-uuid>/<name> */
633 1.1 bouyer static int xenbus_probe_backend_unit(const char *dir,
634 1.1 bouyer const char *type,
635 1.1 bouyer const char *name)
636 1.1 bouyer {
637 1.1 bouyer char *nodename;
638 1.1 bouyer int err;
639 1.1 bouyer
640 1.1 bouyer nodename = kasprintf("%s/%s", dir, name);
641 1.1 bouyer if (!nodename)
642 1.1 bouyer return -ENOMEM;
643 1.1 bouyer
644 1.1 bouyer DPRINTK("%s\n", nodename);
645 1.1 bouyer
646 1.1 bouyer err = xenbus_probe_node(&xenbus_backend, type, nodename);
647 1.1 bouyer kfree(nodename);
648 1.1 bouyer return err;
649 1.1 bouyer }
650 1.1 bouyer
651 1.1 bouyer /* backend/<typename>/<frontend-domid> */
652 1.1 bouyer static int xenbus_probe_backend(const char *type, const char *domid)
653 1.1 bouyer {
654 1.1 bouyer char *nodename;
655 1.1 bouyer int err = 0;
656 1.1 bouyer char **dir;
657 1.1 bouyer unsigned int i, dir_n = 0;
658 1.1 bouyer
659 1.1 bouyer DPRINTK("");
660 1.1 bouyer
661 1.1 bouyer nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
662 1.1 bouyer if (!nodename)
663 1.1 bouyer return -ENOMEM;
664 1.1 bouyer
665 1.1 bouyer dir = xenbus_directory(NULL, nodename, "", &dir_n);
666 1.1 bouyer if (IS_ERR(dir)) {
667 1.1 bouyer kfree(nodename);
668 1.1 bouyer return PTR_ERR(dir);
669 1.1 bouyer }
670 1.1 bouyer
671 1.1 bouyer for (i = 0; i < dir_n; i++) {
672 1.1 bouyer err = xenbus_probe_backend_unit(nodename, type, dir[i]);
673 1.1 bouyer if (err)
674 1.1 bouyer break;
675 1.1 bouyer }
676 1.1 bouyer kfree(dir);
677 1.1 bouyer kfree(nodename);
678 1.1 bouyer return err;
679 1.1 bouyer }
680 1.1 bouyer
681 1.1 bouyer static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
682 1.1 bouyer {
683 1.1 bouyer int err = 0;
684 1.1 bouyer char **dir;
685 1.1 bouyer unsigned int dir_n = 0;
686 1.1 bouyer int i;
687 1.1 bouyer
688 1.1 bouyer dir = xenbus_directory(NULL, bus->root, type, &dir_n);
689 1.1 bouyer if (IS_ERR(dir))
690 1.1 bouyer return PTR_ERR(dir);
691 1.1 bouyer
692 1.1 bouyer for (i = 0; i < dir_n; i++) {
693 1.1 bouyer err = bus->probe(type, dir[i]);
694 1.1 bouyer if (err)
695 1.1 bouyer break;
696 1.1 bouyer }
697 1.1 bouyer kfree(dir);
698 1.1 bouyer return err;
699 1.1 bouyer }
700 1.1 bouyer
701 1.1 bouyer static int xenbus_probe_devices(struct xen_bus_type *bus)
702 1.1 bouyer {
703 1.1 bouyer int err = 0;
704 1.1 bouyer char **dir;
705 1.1 bouyer unsigned int i, dir_n;
706 1.1 bouyer
707 1.1 bouyer dir = xenbus_directory(NULL, bus->root, "", &dir_n);
708 1.1 bouyer if (IS_ERR(dir))
709 1.1 bouyer return PTR_ERR(dir);
710 1.1 bouyer
711 1.1 bouyer for (i = 0; i < dir_n; i++) {
712 1.1 bouyer err = xenbus_probe_device_type(bus, dir[i]);
713 1.1 bouyer if (err)
714 1.1 bouyer break;
715 1.1 bouyer }
716 1.1 bouyer kfree(dir);
717 1.1 bouyer return err;
718 1.1 bouyer }
719 1.1 bouyer
720 1.1 bouyer static unsigned int char_count(const char *str, char c)
721 1.1 bouyer {
722 1.1 bouyer unsigned int i, ret = 0;
723 1.1 bouyer
724 1.1 bouyer for (i = 0; str[i]; i++)
725 1.1 bouyer if (str[i] == c)
726 1.1 bouyer ret++;
727 1.1 bouyer return ret;
728 1.1 bouyer }
729 1.1 bouyer
730 1.1 bouyer static int strsep_len(const char *str, char c, unsigned int len)
731 1.1 bouyer {
732 1.1 bouyer unsigned int i;
733 1.1 bouyer
734 1.1 bouyer for (i = 0; str[i]; i++)
735 1.1 bouyer if (str[i] == c) {
736 1.1 bouyer if (len == 0)
737 1.1 bouyer return i;
738 1.1 bouyer len--;
739 1.1 bouyer }
740 1.1 bouyer return (len == 0) ? i : -ERANGE;
741 1.1 bouyer }
742 1.1 bouyer
743 1.1 bouyer static void dev_changed(const char *node, struct xen_bus_type *bus)
744 1.1 bouyer {
745 1.1 bouyer int exists, rootlen;
746 1.1 bouyer struct xenbus_device *dev;
747 1.1 bouyer char type[BUS_ID_SIZE];
748 1.1 bouyer const char *p, *root;
749 1.1 bouyer
750 1.1 bouyer if (char_count(node, '/') < 2)
751 1.1 bouyer return;
752 1.1 bouyer
753 1.1 bouyer exists = xenbus_exists(NULL, node, "");
754 1.1 bouyer if (!exists) {
755 1.1 bouyer xenbus_cleanup_devices(node, &bus->bus);
756 1.1 bouyer return;
757 1.1 bouyer }
758 1.1 bouyer
759 1.1 bouyer /* backend/<type>/... or device/<type>/... */
760 1.1 bouyer p = strchr(node, '/') + 1;
761 1.1 bouyer snprintf(type, BUS_ID_SIZE, "%.*s", (int)strcspn(p, "/"), p);
762 1.1 bouyer type[BUS_ID_SIZE-1] = '\0';
763 1.1 bouyer
764 1.1 bouyer rootlen = strsep_len(node, '/', bus->levels);
765 1.1 bouyer if (rootlen < 0)
766 1.1 bouyer return;
767 1.1 bouyer root = kasprintf("%.*s", rootlen, node);
768 1.1 bouyer if (!root)
769 1.1 bouyer return;
770 1.1 bouyer
771 1.1 bouyer dev = xenbus_device_find(root, &bus->bus);
772 1.1 bouyer if (!dev)
773 1.1 bouyer xenbus_probe_node(bus, type, root);
774 1.1 bouyer else
775 1.1 bouyer put_device(&dev->dev);
776 1.1 bouyer
777 1.1 bouyer kfree(root);
778 1.1 bouyer }
779 1.1 bouyer
780 1.1 bouyer static void frontend_changed(struct xenbus_watch *watch,
781 1.1 bouyer const char **vec, unsigned int len)
782 1.1 bouyer {
783 1.1 bouyer DPRINTK("");
784 1.1 bouyer
785 1.1 bouyer dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
786 1.1 bouyer }
787 1.1 bouyer
788 1.1 bouyer static void backend_changed(struct xenbus_watch *watch,
789 1.1 bouyer const char **vec, unsigned int len)
790 1.1 bouyer {
791 1.1 bouyer DPRINTK("");
792 1.1 bouyer
793 1.1 bouyer dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
794 1.1 bouyer }
795 1.1 bouyer
796 1.1 bouyer /* We watch for devices appearing and vanishing. */
797 1.1 bouyer static struct xenbus_watch fe_watch = {
798 1.1 bouyer .node = "device",
799 1.1 bouyer .callback = frontend_changed,
800 1.1 bouyer };
801 1.1 bouyer
802 1.1 bouyer static struct xenbus_watch be_watch = {
803 1.1 bouyer .node = "backend",
804 1.1 bouyer .callback = backend_changed,
805 1.1 bouyer };
806 1.1 bouyer
807 1.1 bouyer static int suspend_dev(struct device *dev, void *data)
808 1.1 bouyer {
809 1.1 bouyer int err = 0;
810 1.1 bouyer struct xenbus_driver *drv;
811 1.1 bouyer struct xenbus_device *xdev;
812 1.1 bouyer
813 1.1 bouyer DPRINTK("");
814 1.1 bouyer
815 1.1 bouyer if (dev->driver == NULL)
816 1.1 bouyer return 0;
817 1.1 bouyer drv = to_xenbus_driver(dev->driver);
818 1.1 bouyer xdev = container_of(dev, struct xenbus_device, dev);
819 1.1 bouyer if (drv->suspend)
820 1.1 bouyer err = drv->suspend(xdev);
821 1.1 bouyer if (err)
822 1.1 bouyer printk(KERN_WARNING
823 1.1 bouyer "xenbus: suspend %s failed: %i\n", dev->bus_id, err);
824 1.1 bouyer return 0;
825 1.1 bouyer }
826 1.1 bouyer
827 1.1 bouyer static int resume_dev(struct device *dev, void *data)
828 1.1 bouyer {
829 1.1 bouyer int err;
830 1.1 bouyer struct xenbus_driver *drv;
831 1.1 bouyer struct xenbus_device *xdev;
832 1.1 bouyer
833 1.1 bouyer DPRINTK("");
834 1.1 bouyer
835 1.1 bouyer if (dev->driver == NULL)
836 1.1 bouyer return 0;
837 1.1 bouyer drv = to_xenbus_driver(dev->driver);
838 1.1 bouyer xdev = container_of(dev, struct xenbus_device, dev);
839 1.1 bouyer
840 1.1 bouyer err = talk_to_otherend(xdev);
841 1.1 bouyer if (err) {
842 1.1 bouyer printk(KERN_WARNING
843 1.1 bouyer "xenbus: resume (talk_to_otherend) %s failed: %i\n",
844 1.1 bouyer dev->bus_id, err);
845 1.1 bouyer return err;
846 1.1 bouyer }
847 1.1 bouyer
848 1.1 bouyer if (drv->resume)
849 1.1 bouyer err = drv->resume(xdev);
850 1.1 bouyer if (err)
851 1.1 bouyer printk(KERN_WARNING
852 1.1 bouyer "xenbus: resume %s failed: %i\n", dev->bus_id, err);
853 1.1 bouyer return err;
854 1.1 bouyer }
855 1.1 bouyer
856 1.1 bouyer void xenbus_suspend(void)
857 1.1 bouyer {
858 1.1 bouyer DPRINTK("");
859 1.1 bouyer
860 1.1 bouyer bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
861 1.1 bouyer bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
862 1.1 bouyer xs_suspend();
863 1.1 bouyer }
864 1.1 bouyer EXPORT_SYMBOL(xenbus_suspend);
865 1.1 bouyer
866 1.1 bouyer void xenbus_resume(void)
867 1.1 bouyer {
868 1.1 bouyer xb_init_comms();
869 1.1 bouyer xs_resume();
870 1.1 bouyer bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
871 1.1 bouyer bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
872 1.1 bouyer }
873 1.1 bouyer EXPORT_SYMBOL(xenbus_resume);
874 1.1 bouyer
875 1.1 bouyer
876 1.1 bouyer /* A flag to determine if xenstored is 'ready' (i.e. has started) */
877 1.1 bouyer int xenstored_ready = 0;
878 1.1 bouyer
879 1.1 bouyer
880 1.1 bouyer int register_xenstore_notifier(struct notifier_block *nb)
881 1.1 bouyer {
882 1.1 bouyer int ret = 0;
883 1.1 bouyer
884 1.1 bouyer if (xenstored_ready > 0)
885 1.1 bouyer ret = nb->notifier_call(nb, 0, NULL);
886 1.1 bouyer else
887 1.1 bouyer notifier_chain_register(&xenstore_chain, nb);
888 1.1 bouyer
889 1.1 bouyer return ret;
890 1.1 bouyer }
891 1.1 bouyer EXPORT_SYMBOL(register_xenstore_notifier);
892 1.1 bouyer
893 1.1 bouyer void unregister_xenstore_notifier(struct notifier_block *nb)
894 1.1 bouyer {
895 1.1 bouyer notifier_chain_unregister(&xenstore_chain, nb);
896 1.1 bouyer }
897 1.1 bouyer EXPORT_SYMBOL(unregister_xenstore_notifier);
898 1.1 bouyer
899 1.1 bouyer
900 1.1 bouyer
901 1.1 bouyer void xenbus_probe(void *unused)
902 1.1 bouyer {
903 1.1 bouyer BUG_ON((xenstored_ready <= 0));
904 1.1 bouyer
905 1.1 bouyer /* Enumerate devices in xenstore. */
906 1.1 bouyer xenbus_probe_devices(&xenbus_frontend);
907 1.1 bouyer xenbus_probe_devices(&xenbus_backend);
908 1.1 bouyer
909 1.1 bouyer /* Watch for changes. */
910 1.1 bouyer register_xenbus_watch(&fe_watch);
911 1.1 bouyer register_xenbus_watch(&be_watch);
912 1.1 bouyer
913 1.1 bouyer /* Notify others that xenstore is up */
914 1.1 bouyer notifier_call_chain(&xenstore_chain, 0, NULL);
915 1.1 bouyer }
916 1.1 bouyer
917 1.1 bouyer
918 1.1 bouyer static struct proc_dir_entry *xsd_mfn_intf;
919 1.1 bouyer static struct proc_dir_entry *xsd_port_intf;
920 1.1 bouyer
921 1.1 bouyer
922 1.1 bouyer static int xsd_mfn_read(char *page, char **start, off_t off,
923 1.1 bouyer int count, int *eof, void *data)
924 1.1 bouyer {
925 1.1 bouyer int len;
926 1.1 bouyer len = sprintf(page, "%ld", xen_start_info->store_mfn);
927 1.1 bouyer *eof = 1;
928 1.1 bouyer return len;
929 1.1 bouyer }
930 1.1 bouyer
931 1.1 bouyer static int xsd_port_read(char *page, char **start, off_t off,
932 1.1 bouyer int count, int *eof, void *data)
933 1.1 bouyer {
934 1.1 bouyer int len;
935 1.1 bouyer
936 1.1 bouyer len = sprintf(page, "%d", xen_start_info->store_evtchn);
937 1.1 bouyer *eof = 1;
938 1.1 bouyer return len;
939 1.1 bouyer }
940 1.1 bouyer
941 1.1 bouyer
942 1.1 bouyer static int __init xenbus_probe_init(void)
943 1.1 bouyer {
944 1.1 bouyer int err = 0, dom0;
945 1.1 bouyer
946 1.1 bouyer DPRINTK("");
947 1.1 bouyer
948 1.1 bouyer if (xen_init() < 0) {
949 1.1 bouyer DPRINTK("failed");
950 1.1 bouyer return -ENODEV;
951 1.1 bouyer }
952 1.1 bouyer
953 1.1 bouyer /* Register ourselves with the kernel bus & device subsystems */
954 1.1 bouyer bus_register(&xenbus_frontend.bus);
955 1.1 bouyer bus_register(&xenbus_backend.bus);
956 1.1 bouyer device_register(&xenbus_frontend.dev);
957 1.1 bouyer device_register(&xenbus_backend.dev);
958 1.1 bouyer
959 1.1 bouyer /*
960 1.1 bouyer ** Domain0 doesn't have a store_evtchn or store_mfn yet.
961 1.1 bouyer */
962 1.1 bouyer dom0 = (xen_start_info->store_evtchn == 0);
963 1.1 bouyer
964 1.1 bouyer if (dom0) {
965 1.1 bouyer
966 1.1 bouyer unsigned long page;
967 1.1 bouyer evtchn_op_t op = { 0 };
968 1.1 bouyer int ret;
969 1.1 bouyer
970 1.1 bouyer
971 1.1 bouyer /* Allocate page. */
972 1.1 bouyer page = get_zeroed_page(GFP_KERNEL);
973 1.1 bouyer if (!page)
974 1.1 bouyer return -ENOMEM;
975 1.1 bouyer
976 1.1 bouyer /* We don't refcnt properly, so set reserved on page.
977 1.1 bouyer * (this allocation is permanent) */
978 1.1 bouyer SetPageReserved(virt_to_page(page));
979 1.1 bouyer
980 1.1 bouyer xen_start_info->store_mfn =
981 1.1 bouyer pfn_to_mfn(virt_to_phys((void *)page) >>
982 1.1 bouyer PAGE_SHIFT);
983 1.1 bouyer
984 1.1 bouyer /* Next allocate a local port which xenstored can bind to */
985 1.1 bouyer op.cmd = EVTCHNOP_alloc_unbound;
986 1.1 bouyer op.u.alloc_unbound.dom = DOMID_SELF;
987 1.1 bouyer op.u.alloc_unbound.remote_dom = 0;
988 1.1 bouyer
989 1.1 bouyer ret = HYPERVISOR_event_channel_op(&op);
990 1.1 bouyer BUG_ON(ret);
991 1.1 bouyer xen_start_info->store_evtchn = op.u.alloc_unbound.port;
992 1.1 bouyer
993 1.1 bouyer /* And finally publish the above info in /proc/xen */
994 1.1 bouyer if((xsd_mfn_intf = create_xen_proc_entry("xsd_mfn", 0400)))
995 1.1 bouyer xsd_mfn_intf->read_proc = xsd_mfn_read;
996 1.1 bouyer if((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400)))
997 1.1 bouyer xsd_port_intf->read_proc = xsd_port_read;
998 1.1 bouyer }
999 1.1 bouyer
1000 1.1 bouyer /* Initialize the interface to xenstore. */
1001 1.1 bouyer err = xs_init();
1002 1.1 bouyer if (err) {
1003 1.1 bouyer printk(KERN_WARNING
1004 1.1 bouyer "XENBUS: Error initializing xenstore comms: %i\n", err);
1005 1.1 bouyer return err;
1006 1.1 bouyer }
1007 1.1 bouyer
1008 1.1 bouyer if (!dom0) {
1009 1.1 bouyer xenstored_ready = 1;
1010 1.1 bouyer xenbus_probe(NULL);
1011 1.1 bouyer }
1012 1.1 bouyer
1013 1.1 bouyer return 0;
1014 1.1 bouyer }
1015 1.1 bouyer
1016 1.1 bouyer postcore_initcall(xenbus_probe_init);
1017 1.1 bouyer
1018 1.1 bouyer /*
1019 1.1 bouyer * Local variables:
1020 1.1 bouyer * c-file-style: "linux"
1021 1.1 bouyer * indent-tabs-mode: t
1022 1.1 bouyer * c-indent-level: 8
1023 1.1 bouyer * c-basic-offset: 8
1024 1.1 bouyer * tab-width: 8
1025 1.1 bouyer * End:
1026 1.1 bouyer */
1027