ia64/xen-unstable

view linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @ 9551:f6a7f2657ff3

Disable xen bus and grant tables when supervisor_mode_kernel is enabled.
Neither of these features are useful/available in this mode since only a
single domain is supported.

Do not attempt to initialise xen bus when supervisor_mode_kernel is
enabled.

Do not BUG_ON() failure to setup grant tables, future versions
of supervisor_mode_kernel may return -ENOSYS here.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author Ian.Campbell@xensource.com
date Fri Mar 31 11:04:42 2006 +0100 (2006-03-31)
parents 24aa3bd826ff
children 11228d42cff3
line source
1 /******************************************************************************
2 * Talks to Xen Store to figure out what devices we have.
3 *
4 * Copyright (C) 2005 Rusty Russell, IBM Corporation
5 * Copyright (C) 2005 Mike Wray, Hewlett-Packard
6 * Copyright (C) 2005 XenSource Ltd
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation; or, when distributed
11 * separately from the Linux kernel or incorporated into other
12 * software packages, subject to the following license:
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this source file (the "Software"), to deal in the Software without
16 * restriction, including without limitation the rights to use, copy, modify,
17 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
18 * and to permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 * IN THE SOFTWARE.
31 */
33 #define DPRINTK(fmt, args...) \
34 pr_debug("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
36 #include <linux/kernel.h>
37 #include <linux/err.h>
38 #include <linux/string.h>
39 #include <linux/ctype.h>
40 #include <linux/fcntl.h>
41 #include <linux/mm.h>
42 #include <linux/notifier.h>
43 #include <linux/kthread.h>
45 #include <asm/io.h>
46 #include <asm/page.h>
47 #include <asm/pgtable.h>
48 #include <asm/hypervisor.h>
49 #include <xen/xenbus.h>
50 #include <xen/xen_proc.h>
51 #include <xen/evtchn.h>
53 #include "xenbus_comms.h"
55 extern struct mutex xenwatch_mutex;
57 static struct notifier_block *xenstore_chain;
59 /* If something in array of ids matches this device, return it. */
60 static const struct xenbus_device_id *
61 match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev)
62 {
63 for (; *arr->devicetype != '\0'; arr++) {
64 if (!strcmp(arr->devicetype, dev->devicetype))
65 return arr;
66 }
67 return NULL;
68 }
70 static int xenbus_match(struct device *_dev, struct device_driver *_drv)
71 {
72 struct xenbus_driver *drv = to_xenbus_driver(_drv);
74 if (!drv->ids)
75 return 0;
77 return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
78 }
80 struct xen_bus_type
81 {
82 char *root;
83 unsigned int levels;
84 int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
85 int (*probe)(const char *type, const char *dir);
86 struct bus_type bus;
87 struct device dev;
88 };
91 /* device/<type>/<id> => <type>-<id> */
92 static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
93 {
94 nodename = strchr(nodename, '/');
95 if (!nodename || strlen(nodename + 1) >= BUS_ID_SIZE) {
96 printk(KERN_WARNING "XENBUS: bad frontend %s\n", nodename);
97 return -EINVAL;
98 }
100 strlcpy(bus_id, nodename + 1, BUS_ID_SIZE);
101 if (!strchr(bus_id, '/')) {
102 printk(KERN_WARNING "XENBUS: bus_id %s no slash\n", bus_id);
103 return -EINVAL;
104 }
105 *strchr(bus_id, '/') = '-';
106 return 0;
107 }
110 static void free_otherend_details(struct xenbus_device *dev)
111 {
112 kfree(dev->otherend);
113 dev->otherend = NULL;
114 }
117 static void free_otherend_watch(struct xenbus_device *dev)
118 {
119 if (dev->otherend_watch.node) {
120 unregister_xenbus_watch(&dev->otherend_watch);
121 kfree(dev->otherend_watch.node);
122 dev->otherend_watch.node = NULL;
123 }
124 }
127 static int read_otherend_details(struct xenbus_device *xendev,
128 char *id_node, char *path_node)
129 {
130 int err = xenbus_gather(XBT_NULL, xendev->nodename,
131 id_node, "%i", &xendev->otherend_id,
132 path_node, NULL, &xendev->otherend,
133 NULL);
134 if (err) {
135 xenbus_dev_fatal(xendev, err,
136 "reading other end details from %s",
137 xendev->nodename);
138 return err;
139 }
140 if (strlen(xendev->otherend) == 0 ||
141 !xenbus_exists(XBT_NULL, xendev->otherend, "")) {
142 xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
143 xendev->nodename);
144 free_otherend_details(xendev);
145 return -ENOENT;
146 }
148 return 0;
149 }
152 static int read_backend_details(struct xenbus_device *xendev)
153 {
154 return read_otherend_details(xendev, "backend-id", "backend");
155 }
158 static int read_frontend_details(struct xenbus_device *xendev)
159 {
160 return read_otherend_details(xendev, "frontend-id", "frontend");
161 }
164 /* Bus type for frontend drivers. */
165 static int xenbus_probe_frontend(const char *type, const char *name);
166 static struct xen_bus_type xenbus_frontend = {
167 .root = "device",
168 .levels = 2, /* device/type/<id> */
169 .get_bus_id = frontend_bus_id,
170 .probe = xenbus_probe_frontend,
171 .bus = {
172 .name = "xen",
173 .match = xenbus_match,
174 },
175 .dev = {
176 .bus_id = "xen",
177 },
178 };
180 /* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */
181 static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
182 {
183 int domid, err;
184 const char *devid, *type, *frontend;
185 unsigned int typelen;
187 type = strchr(nodename, '/');
188 if (!type)
189 return -EINVAL;
190 type++;
191 typelen = strcspn(type, "/");
192 if (!typelen || type[typelen] != '/')
193 return -EINVAL;
195 devid = strrchr(nodename, '/') + 1;
197 err = xenbus_gather(XBT_NULL, nodename, "frontend-id", "%i", &domid,
198 "frontend", NULL, &frontend,
199 NULL);
200 if (err)
201 return err;
202 if (strlen(frontend) == 0)
203 err = -ERANGE;
204 if (!err && !xenbus_exists(XBT_NULL, frontend, ""))
205 err = -ENOENT;
207 kfree(frontend);
209 if (err)
210 return err;
212 if (snprintf(bus_id, BUS_ID_SIZE,
213 "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
214 return -ENOSPC;
215 return 0;
216 }
218 static int xenbus_uevent_backend(struct device *dev, char **envp,
219 int num_envp, char *buffer, int buffer_size);
220 static int xenbus_probe_backend(const char *type, const char *domid);
221 static struct xen_bus_type xenbus_backend = {
222 .root = "backend",
223 .levels = 3, /* backend/type/<frontend>/<id> */
224 .get_bus_id = backend_bus_id,
225 .probe = xenbus_probe_backend,
226 .bus = {
227 .name = "xen-backend",
228 .match = xenbus_match,
229 .uevent = xenbus_uevent_backend,
230 },
231 .dev = {
232 .bus_id = "xen-backend",
233 },
234 };
236 static int xenbus_uevent_backend(struct device *dev, char **envp,
237 int num_envp, char *buffer, int buffer_size)
238 {
239 struct xenbus_device *xdev;
240 struct xenbus_driver *drv;
241 int i = 0;
242 int length = 0;
244 DPRINTK("");
246 if (dev == NULL)
247 return -ENODEV;
249 xdev = to_xenbus_device(dev);
250 if (xdev == NULL)
251 return -ENODEV;
253 /* stuff we want to pass to /sbin/hotplug */
254 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
255 "XENBUS_TYPE=%s", xdev->devicetype);
257 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
258 "XENBUS_PATH=%s", xdev->nodename);
260 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
261 "XENBUS_BASE_PATH=%s", xenbus_backend.root);
263 /* terminate, set to next free slot, shrink available space */
264 envp[i] = NULL;
265 envp = &envp[i];
266 num_envp -= i;
267 buffer = &buffer[length];
268 buffer_size -= length;
270 if (dev->driver) {
271 drv = to_xenbus_driver(dev->driver);
272 if (drv && drv->uevent)
273 return drv->uevent(xdev, envp, num_envp, buffer,
274 buffer_size);
275 }
277 return 0;
278 }
280 static void otherend_changed(struct xenbus_watch *watch,
281 const char **vec, unsigned int len)
282 {
283 struct xenbus_device *dev =
284 container_of(watch, struct xenbus_device, otherend_watch);
285 struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
286 XenbusState state;
288 /* Protect us against watches firing on old details when the otherend
289 details change, say immediately after a resume. */
290 if (!dev->otherend ||
291 strncmp(dev->otherend, vec[XS_WATCH_PATH],
292 strlen(dev->otherend))) {
293 DPRINTK("Ignoring watch at %s", vec[XS_WATCH_PATH]);
294 return;
295 }
297 state = xenbus_read_driver_state(dev->otherend);
299 DPRINTK("state is %d, %s, %s",
300 state, dev->otherend_watch.node, vec[XS_WATCH_PATH]);
301 if (drv->otherend_changed)
302 drv->otherend_changed(dev, state);
303 }
306 static int talk_to_otherend(struct xenbus_device *dev)
307 {
308 struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
310 free_otherend_watch(dev);
311 free_otherend_details(dev);
313 return drv->read_otherend_details(dev);
314 }
317 static int watch_otherend(struct xenbus_device *dev)
318 {
319 return xenbus_watch_path2(dev, dev->otherend, "state",
320 &dev->otherend_watch, otherend_changed);
321 }
324 static int xenbus_dev_probe(struct device *_dev)
325 {
326 struct xenbus_device *dev = to_xenbus_device(_dev);
327 struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
328 const struct xenbus_device_id *id;
329 int err;
331 DPRINTK("");
333 if (!drv->probe) {
334 err = -ENODEV;
335 goto fail;
336 }
338 id = match_device(drv->ids, dev);
339 if (!id) {
340 err = -ENODEV;
341 goto fail;
342 }
344 err = talk_to_otherend(dev);
345 if (err) {
346 printk(KERN_WARNING
347 "xenbus_probe: talk_to_otherend on %s failed.\n",
348 dev->nodename);
349 return err;
350 }
352 err = drv->probe(dev, id);
353 if (err)
354 goto fail;
356 err = watch_otherend(dev);
357 if (err) {
358 printk(KERN_WARNING
359 "xenbus_probe: watch_otherend on %s failed.\n",
360 dev->nodename);
361 return err;
362 }
364 return 0;
365 fail:
366 xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
367 xenbus_switch_state(dev, XenbusStateClosed);
368 return -ENODEV;
369 }
371 static int xenbus_dev_remove(struct device *_dev)
372 {
373 struct xenbus_device *dev = to_xenbus_device(_dev);
374 struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
376 DPRINTK("");
378 free_otherend_watch(dev);
379 free_otherend_details(dev);
381 if (drv->remove)
382 drv->remove(dev);
384 xenbus_switch_state(dev, XenbusStateClosed);
385 return 0;
386 }
388 static int xenbus_register_driver_common(struct xenbus_driver *drv,
389 struct xen_bus_type *bus)
390 {
391 int ret;
393 drv->driver.name = drv->name;
394 drv->driver.bus = &bus->bus;
395 drv->driver.owner = drv->owner;
396 drv->driver.probe = xenbus_dev_probe;
397 drv->driver.remove = xenbus_dev_remove;
399 mutex_lock(&xenwatch_mutex);
400 ret = driver_register(&drv->driver);
401 mutex_unlock(&xenwatch_mutex);
402 return ret;
403 }
405 int xenbus_register_frontend(struct xenbus_driver *drv)
406 {
407 drv->read_otherend_details = read_backend_details;
409 return xenbus_register_driver_common(drv, &xenbus_frontend);
410 }
411 EXPORT_SYMBOL_GPL(xenbus_register_frontend);
413 int xenbus_register_backend(struct xenbus_driver *drv)
414 {
415 drv->read_otherend_details = read_frontend_details;
417 return xenbus_register_driver_common(drv, &xenbus_backend);
418 }
419 EXPORT_SYMBOL_GPL(xenbus_register_backend);
421 void xenbus_unregister_driver(struct xenbus_driver *drv)
422 {
423 driver_unregister(&drv->driver);
424 }
425 EXPORT_SYMBOL_GPL(xenbus_unregister_driver);
427 struct xb_find_info
428 {
429 struct xenbus_device *dev;
430 const char *nodename;
431 };
433 static int cmp_dev(struct device *dev, void *data)
434 {
435 struct xenbus_device *xendev = to_xenbus_device(dev);
436 struct xb_find_info *info = data;
438 if (!strcmp(xendev->nodename, info->nodename)) {
439 info->dev = xendev;
440 get_device(dev);
441 return 1;
442 }
443 return 0;
444 }
446 struct xenbus_device *xenbus_device_find(const char *nodename,
447 struct bus_type *bus)
448 {
449 struct xb_find_info info = { .dev = NULL, .nodename = nodename };
451 bus_for_each_dev(bus, NULL, &info, cmp_dev);
452 return info.dev;
453 }
455 static int cleanup_dev(struct device *dev, void *data)
456 {
457 struct xenbus_device *xendev = to_xenbus_device(dev);
458 struct xb_find_info *info = data;
459 int len = strlen(info->nodename);
461 DPRINTK("%s", info->nodename);
463 /* Match the info->nodename path, or any subdirectory of that path. */
464 if (strncmp(xendev->nodename, info->nodename, len))
465 return 0;
467 /* If the node name is longer, ensure it really is a subdirectory. */
468 if ((strlen(xendev->nodename) > len) && (xendev->nodename[len] != '/'))
469 return 0;
471 info->dev = xendev;
472 get_device(dev);
473 return 1;
474 }
476 static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
477 {
478 struct xb_find_info info = { .nodename = path };
480 do {
481 info.dev = NULL;
482 bus_for_each_dev(bus, NULL, &info, cleanup_dev);
483 if (info.dev) {
484 device_unregister(&info.dev->dev);
485 put_device(&info.dev->dev);
486 }
487 } while (info.dev);
488 }
490 static void xenbus_dev_release(struct device *dev)
491 {
492 if (dev)
493 kfree(to_xenbus_device(dev));
494 }
496 /* Simplified asprintf. */
497 char *kasprintf(const char *fmt, ...)
498 {
499 va_list ap;
500 unsigned int len;
501 char *p, dummy[1];
503 va_start(ap, fmt);
504 /* FIXME: vsnprintf has a bug, NULL should work */
505 len = vsnprintf(dummy, 0, fmt, ap);
506 va_end(ap);
508 p = kmalloc(len + 1, GFP_KERNEL);
509 if (!p)
510 return NULL;
511 va_start(ap, fmt);
512 vsprintf(p, fmt, ap);
513 va_end(ap);
514 return p;
515 }
517 static ssize_t xendev_show_nodename(struct device *dev,
518 struct device_attribute *attr, char *buf)
519 {
520 return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
521 }
522 DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
524 static ssize_t xendev_show_devtype(struct device *dev,
525 struct device_attribute *attr, char *buf)
526 {
527 return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
528 }
529 DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
532 static int xenbus_probe_node(struct xen_bus_type *bus,
533 const char *type,
534 const char *nodename)
535 {
536 int err;
537 struct xenbus_device *xendev;
538 size_t stringlen;
539 char *tmpstring;
541 XenbusState state = xenbus_read_driver_state(nodename);
543 if (state != XenbusStateInitialising) {
544 /* Device is not new, so ignore it. This can happen if a
545 device is going away after switching to Closed. */
546 return 0;
547 }
549 stringlen = strlen(nodename) + 1 + strlen(type) + 1;
550 xendev = kzalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
551 if (!xendev)
552 return -ENOMEM;
554 /* Copy the strings into the extra space. */
556 tmpstring = (char *)(xendev + 1);
557 strcpy(tmpstring, nodename);
558 xendev->nodename = tmpstring;
560 tmpstring += strlen(tmpstring) + 1;
561 strcpy(tmpstring, type);
562 xendev->devicetype = tmpstring;
564 xendev->dev.parent = &bus->dev;
565 xendev->dev.bus = &bus->bus;
566 xendev->dev.release = xenbus_dev_release;
568 err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
569 if (err)
570 goto fail;
572 /* Register with generic device framework. */
573 err = device_register(&xendev->dev);
574 if (err)
575 goto fail;
577 device_create_file(&xendev->dev, &dev_attr_nodename);
578 device_create_file(&xendev->dev, &dev_attr_devtype);
580 return 0;
581 fail:
582 kfree(xendev);
583 return err;
584 }
586 /* device/<typename>/<name> */
587 static int xenbus_probe_frontend(const char *type, const char *name)
588 {
589 char *nodename;
590 int err;
592 nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name);
593 if (!nodename)
594 return -ENOMEM;
596 DPRINTK("%s", nodename);
598 err = xenbus_probe_node(&xenbus_frontend, type, nodename);
599 kfree(nodename);
600 return err;
601 }
603 /* backend/<typename>/<frontend-uuid>/<name> */
604 static int xenbus_probe_backend_unit(const char *dir,
605 const char *type,
606 const char *name)
607 {
608 char *nodename;
609 int err;
611 nodename = kasprintf("%s/%s", dir, name);
612 if (!nodename)
613 return -ENOMEM;
615 DPRINTK("%s\n", nodename);
617 err = xenbus_probe_node(&xenbus_backend, type, nodename);
618 kfree(nodename);
619 return err;
620 }
622 /* backend/<typename>/<frontend-domid> */
623 static int xenbus_probe_backend(const char *type, const char *domid)
624 {
625 char *nodename;
626 int err = 0;
627 char **dir;
628 unsigned int i, dir_n = 0;
630 DPRINTK("");
632 nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
633 if (!nodename)
634 return -ENOMEM;
636 dir = xenbus_directory(XBT_NULL, nodename, "", &dir_n);
637 if (IS_ERR(dir)) {
638 kfree(nodename);
639 return PTR_ERR(dir);
640 }
642 for (i = 0; i < dir_n; i++) {
643 err = xenbus_probe_backend_unit(nodename, type, dir[i]);
644 if (err)
645 break;
646 }
647 kfree(dir);
648 kfree(nodename);
649 return err;
650 }
652 static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
653 {
654 int err = 0;
655 char **dir;
656 unsigned int dir_n = 0;
657 int i;
659 dir = xenbus_directory(XBT_NULL, bus->root, type, &dir_n);
660 if (IS_ERR(dir))
661 return PTR_ERR(dir);
663 for (i = 0; i < dir_n; i++) {
664 err = bus->probe(type, dir[i]);
665 if (err)
666 break;
667 }
668 kfree(dir);
669 return err;
670 }
672 static int xenbus_probe_devices(struct xen_bus_type *bus)
673 {
674 int err = 0;
675 char **dir;
676 unsigned int i, dir_n;
678 dir = xenbus_directory(XBT_NULL, bus->root, "", &dir_n);
679 if (IS_ERR(dir))
680 return PTR_ERR(dir);
682 for (i = 0; i < dir_n; i++) {
683 err = xenbus_probe_device_type(bus, dir[i]);
684 if (err)
685 break;
686 }
687 kfree(dir);
688 return err;
689 }
691 static unsigned int char_count(const char *str, char c)
692 {
693 unsigned int i, ret = 0;
695 for (i = 0; str[i]; i++)
696 if (str[i] == c)
697 ret++;
698 return ret;
699 }
701 static int strsep_len(const char *str, char c, unsigned int len)
702 {
703 unsigned int i;
705 for (i = 0; str[i]; i++)
706 if (str[i] == c) {
707 if (len == 0)
708 return i;
709 len--;
710 }
711 return (len == 0) ? i : -ERANGE;
712 }
714 static void dev_changed(const char *node, struct xen_bus_type *bus)
715 {
716 int exists, rootlen;
717 struct xenbus_device *dev;
718 char type[BUS_ID_SIZE];
719 const char *p, *root;
721 if (char_count(node, '/') < 2)
722 return;
724 exists = xenbus_exists(XBT_NULL, node, "");
725 if (!exists) {
726 xenbus_cleanup_devices(node, &bus->bus);
727 return;
728 }
730 /* backend/<type>/... or device/<type>/... */
731 p = strchr(node, '/') + 1;
732 snprintf(type, BUS_ID_SIZE, "%.*s", (int)strcspn(p, "/"), p);
733 type[BUS_ID_SIZE-1] = '\0';
735 rootlen = strsep_len(node, '/', bus->levels);
736 if (rootlen < 0)
737 return;
738 root = kasprintf("%.*s", rootlen, node);
739 if (!root)
740 return;
742 dev = xenbus_device_find(root, &bus->bus);
743 if (!dev)
744 xenbus_probe_node(bus, type, root);
745 else
746 put_device(&dev->dev);
748 kfree(root);
749 }
751 static void frontend_changed(struct xenbus_watch *watch,
752 const char **vec, unsigned int len)
753 {
754 DPRINTK("");
756 dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
757 }
759 static void backend_changed(struct xenbus_watch *watch,
760 const char **vec, unsigned int len)
761 {
762 DPRINTK("");
764 dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
765 }
767 /* We watch for devices appearing and vanishing. */
768 static struct xenbus_watch fe_watch = {
769 .node = "device",
770 .callback = frontend_changed,
771 };
773 static struct xenbus_watch be_watch = {
774 .node = "backend",
775 .callback = backend_changed,
776 };
778 static int suspend_dev(struct device *dev, void *data)
779 {
780 int err = 0;
781 struct xenbus_driver *drv;
782 struct xenbus_device *xdev;
784 DPRINTK("");
786 if (dev->driver == NULL)
787 return 0;
788 drv = to_xenbus_driver(dev->driver);
789 xdev = container_of(dev, struct xenbus_device, dev);
790 if (drv->suspend)
791 err = drv->suspend(xdev);
792 if (err)
793 printk(KERN_WARNING
794 "xenbus: suspend %s failed: %i\n", dev->bus_id, err);
795 return 0;
796 }
798 static int resume_dev(struct device *dev, void *data)
799 {
800 int err;
801 struct xenbus_driver *drv;
802 struct xenbus_device *xdev;
804 DPRINTK("");
806 if (dev->driver == NULL)
807 return 0;
808 drv = to_xenbus_driver(dev->driver);
809 xdev = container_of(dev, struct xenbus_device, dev);
811 err = talk_to_otherend(xdev);
812 if (err) {
813 printk(KERN_WARNING
814 "xenbus: resume (talk_to_otherend) %s failed: %i\n",
815 dev->bus_id, err);
816 return err;
817 }
819 err = watch_otherend(xdev);
820 if (err) {
821 printk(KERN_WARNING
822 "xenbus_probe: resume (watch_otherend) %s failed: "
823 "%d.\n", dev->bus_id, err);
824 return err;
825 }
827 if (drv->resume)
828 err = drv->resume(xdev);
829 if (err)
830 printk(KERN_WARNING
831 "xenbus: resume %s failed: %i\n", dev->bus_id, err);
832 return err;
833 }
835 void xenbus_suspend(void)
836 {
837 DPRINTK("");
839 bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
840 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
841 xs_suspend();
842 }
843 EXPORT_SYMBOL_GPL(xenbus_suspend);
845 void xenbus_resume(void)
846 {
847 xb_init_comms();
848 xs_resume();
849 bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
850 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
851 }
852 EXPORT_SYMBOL_GPL(xenbus_resume);
855 /* A flag to determine if xenstored is 'ready' (i.e. has started) */
856 int xenstored_ready = 0;
859 int register_xenstore_notifier(struct notifier_block *nb)
860 {
861 int ret = 0;
863 if (xenstored_ready > 0)
864 ret = nb->notifier_call(nb, 0, NULL);
865 else
866 notifier_chain_register(&xenstore_chain, nb);
868 return ret;
869 }
870 EXPORT_SYMBOL_GPL(register_xenstore_notifier);
872 void unregister_xenstore_notifier(struct notifier_block *nb)
873 {
874 notifier_chain_unregister(&xenstore_chain, nb);
875 }
876 EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
879 static int all_devices_ready_(struct device *dev, void *data)
880 {
881 struct xenbus_device *xendev = to_xenbus_device(dev);
882 int *result = data;
884 if (xendev->state != XenbusStateConnected) {
885 result = 0;
886 return 1;
887 }
889 return 0;
890 }
893 static int all_devices_ready(void)
894 {
895 int ready = 1;
896 bus_for_each_dev(&xenbus_frontend.bus, NULL, &ready,
897 all_devices_ready_);
898 return ready;
899 }
902 void xenbus_probe(void *unused)
903 {
904 int i;
906 BUG_ON((xenstored_ready <= 0));
908 /* Enumerate devices in xenstore. */
909 xenbus_probe_devices(&xenbus_frontend);
910 xenbus_probe_devices(&xenbus_backend);
912 /* Watch for changes. */
913 register_xenbus_watch(&fe_watch);
914 register_xenbus_watch(&be_watch);
916 /* Notify others that xenstore is up */
917 notifier_call_chain(&xenstore_chain, 0, NULL);
919 /* On a 10 second timeout, waiting for all devices currently
920 configured. We need to do this to guarantee that the filesystems
921 and / or network devices needed for boot are available, before we
922 can allow the boot to proceed.
924 A possible improvement here would be to have the tools add a
925 per-device flag to the store entry, indicating whether it is needed
926 at boot time. This would allow people who knew what they were
927 doing to accelerate their boot slightly, but of course needs tools
928 or manual intervention to set up those flags correctly.
929 */
930 for (i = 0; i < 10 * HZ; i++) {
931 if (all_devices_ready())
932 return;
934 set_current_state(TASK_INTERRUPTIBLE);
935 schedule_timeout(1);
936 }
938 printk(KERN_WARNING
939 "XENBUS: Timeout connecting to devices!\n");
940 }
943 static struct file_operations xsd_kva_fops;
944 static struct proc_dir_entry *xsd_kva_intf;
945 static struct proc_dir_entry *xsd_port_intf;
947 static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
948 {
949 size_t size = vma->vm_end - vma->vm_start;
951 if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0))
952 return -EINVAL;
954 if (remap_pfn_range(vma, vma->vm_start,
955 mfn_to_pfn(xen_start_info->store_mfn),
956 size, vma->vm_page_prot))
957 return -EAGAIN;
959 return 0;
960 }
962 static int xsd_kva_read(char *page, char **start, off_t off,
963 int count, int *eof, void *data)
964 {
965 int len;
967 len = sprintf(page, "0x%p", mfn_to_virt(xen_start_info->store_mfn));
968 *eof = 1;
969 return len;
970 }
972 static int xsd_port_read(char *page, char **start, off_t off,
973 int count, int *eof, void *data)
974 {
975 int len;
977 len = sprintf(page, "%d", xen_start_info->store_evtchn);
978 *eof = 1;
979 return len;
980 }
983 static int __init xenbus_probe_init(void)
984 {
985 int err = 0, dom0;
987 DPRINTK("");
989 if (xen_init() < 0) {
990 DPRINTK("failed");
991 return -ENODEV;
992 }
994 /* Register ourselves with the kernel bus & device subsystems */
995 bus_register(&xenbus_frontend.bus);
996 bus_register(&xenbus_backend.bus);
997 device_register(&xenbus_frontend.dev);
998 device_register(&xenbus_backend.dev);
1000 /*
1001 * The supervisor_mode_kernel feature only allows a single
1002 * domain so there is no need to initialise event channels
1003 * etc.
1004 */
1005 if (xen_feature(XENFEAT_supervisor_mode_kernel))
1006 return -ENODEV;
1008 /*
1009 * Domain0 doesn't have a store_evtchn or store_mfn yet.
1010 */
1011 dom0 = (xen_start_info->store_evtchn == 0);
1013 if (dom0) {
1015 unsigned long page;
1016 evtchn_op_t op = { 0 };
1017 int ret;
1020 /* Allocate page. */
1021 page = get_zeroed_page(GFP_KERNEL);
1022 if (!page)
1023 return -ENOMEM;
1025 xen_start_info->store_mfn =
1026 pfn_to_mfn(virt_to_phys((void *)page) >>
1027 PAGE_SHIFT);
1029 /* Next allocate a local port which xenstored can bind to */
1030 op.cmd = EVTCHNOP_alloc_unbound;
1031 op.u.alloc_unbound.dom = DOMID_SELF;
1032 op.u.alloc_unbound.remote_dom = 0;
1034 ret = HYPERVISOR_event_channel_op(&op);
1035 BUG_ON(ret);
1036 xen_start_info->store_evtchn = op.u.alloc_unbound.port;
1038 /* And finally publish the above info in /proc/xen */
1039 xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0600);
1040 if (xsd_kva_intf) {
1041 memcpy(&xsd_kva_fops, xsd_kva_intf->proc_fops,
1042 sizeof(xsd_kva_fops));
1043 xsd_kva_fops.mmap = xsd_kva_mmap;
1044 xsd_kva_intf->proc_fops = &xsd_kva_fops;
1045 xsd_kva_intf->read_proc = xsd_kva_read;
1047 xsd_port_intf = create_xen_proc_entry("xsd_port", 0400);
1048 if (xsd_port_intf)
1049 xsd_port_intf->read_proc = xsd_port_read;
1050 } else
1051 xenstored_ready = 1;
1053 /* Initialize the interface to xenstore. */
1054 err = xs_init();
1055 if (err) {
1056 printk(KERN_WARNING
1057 "XENBUS: Error initializing xenstore comms: %i\n", err);
1058 return err;
1061 if (!dom0)
1062 xenbus_probe(NULL);
1064 return 0;
1067 postcore_initcall(xenbus_probe_init);
1069 /*
1070 * Local variables:
1071 * c-file-style: "linux"
1072 * indent-tabs-mode: t
1073 * c-indent-level: 8
1074 * c-basic-offset: 8
1075 * tab-width: 8
1076 * End:
1077 */