The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/xen/xenbus/xenbus_probe_backend.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /******************************************************************************
    2  * Talks to Xen Store to figure out what devices we have (backend half).
    3  *
    4  * Copyright (C) 2005 Rusty Russell, IBM Corporation
    5  * Copyright (C) 2005 Mike Wray, Hewlett-Packard
    6  * Copyright (C) 2005, 2006 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  */
   32 #if 0
   33 #define DPRINTK(fmt, args...) \
   34     printf("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
   35 #else
   36 #define DPRINTK(fmt, args...) ((void)0)
   37 #endif
   38 
   39 #include <sys/cdefs.h>
   40 __FBSDID("$FreeBSD: releng/8.1/sys/xen/xenbus/xenbus_probe_backend.c 186557 2008-12-29 06:31:03Z kmacy $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/types.h>
   44 #include <sys/cdefs.h>
   45 #include <sys/time.h>
   46 #include <sys/sema.h>
   47 #include <sys/eventhandler.h>
   48 #include <sys/errno.h>
   49 #include <sys/kernel.h>
   50 #include <sys/malloc.h>
   51 #include <sys/module.h>
   52 #include <sys/conf.h>
   53 #include <sys/systm.h>
   54 #include <sys/syslog.h>
   55 #include <sys/proc.h>
   56 #include <sys/bus.h>
   57 #include <sys/sx.h>
   58 
   59 #include <machine/xen/xen-os.h>
   60 #include <xen/hypervisor.h>
   61 #include <machine/xen/xenbus.h>
   62 #include <machine/stdarg.h>
   63 
   64 #include <xen/evtchn.h>
   65 #include <xen/xenbus/xenbus_comms.h>
   66 
   67 #define BUG_ON        PANIC_IF
   68 #define semaphore     sema
   69 #define rw_semaphore  sema
   70 #define DEFINE_SPINLOCK(lock) struct mtx lock
   71 #define DECLARE_MUTEX(lock) struct sema lock
   72 #define u32           uint32_t
   73 #define list_del(head, ent)      TAILQ_REMOVE(head, ent, list) 
   74 #define simple_strtoul strtoul
   75 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
   76 #define list_empty    TAILQ_EMPTY
   77 
   78 extern struct xendev_list_head xenbus_device_backend_list;
   79 #if 0
   80 static int xenbus_uevent_backend(struct device *dev, char **envp,
   81                                  int num_envp, char *buffer, int buffer_size);
   82 #endif
   83 static int xenbus_probe_backend(const char *type, const char *domid);
   84 
   85 static int read_frontend_details(struct xenbus_device *xendev)
   86 {
   87         return read_otherend_details(xendev, "frontend-id", "frontend");
   88 }
   89 
   90 /* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */
   91 static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
   92 {
   93         int domid, err;
   94         const char *devid, *type, *frontend;
   95         unsigned int typelen;
   96 
   97         type = strchr(nodename, '/');
   98         if (!type)
   99                 return -EINVAL;
  100         type++;
  101         typelen = strcspn(type, "/");
  102         if (!typelen || type[typelen] != '/')
  103                 return -EINVAL;
  104 
  105         devid = strrchr(nodename, '/') + 1;
  106 
  107         err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid,
  108                             "frontend", NULL, &frontend,
  109                             NULL);
  110         if (err)
  111                 return err;
  112         if (strlen(frontend) == 0)
  113                 err = -ERANGE;
  114         if (!err && !xenbus_exists(XBT_NIL, frontend, ""))
  115                 err = -ENOENT;
  116         kfree(frontend);
  117 
  118         if (err)
  119                 return err;
  120 
  121         if (snprintf(bus_id, BUS_ID_SIZE,
  122                      "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
  123                 return -ENOSPC;
  124         return 0;
  125 }
  126 
  127 static struct xen_bus_type xenbus_backend = {
  128         .root = "backend",
  129         .levels = 3,            /* backend/type/<frontend>/<id> */
  130         .get_bus_id = backend_bus_id,
  131         .probe = xenbus_probe_backend,
  132         .bus = &xenbus_device_backend_list,
  133         
  134 #if 0
  135         .error = -ENODEV,
  136         .bus = {
  137                 .name     = "xen-backend",
  138                 .match    = xenbus_match,
  139                 .probe    = xenbus_dev_probe,
  140                 .remove   = xenbus_dev_remove,
  141 //              .shutdown = xenbus_dev_shutdown,
  142                 .uevent   = xenbus_uevent_backend,
  143         },
  144         .dev = {
  145                 .bus_id = "xen-backend",
  146         },
  147 #endif  
  148 };
  149 
  150 #if 0
  151 static int xenbus_uevent_backend(struct device *dev, char **envp,
  152                                  int num_envp, char *buffer, int buffer_size)
  153 {
  154         struct xenbus_device *xdev;
  155         struct xenbus_driver *drv;
  156         int i = 0;
  157         int length = 0;
  158 
  159         DPRINTK("");
  160 
  161         if (dev == NULL)
  162                 return -ENODEV;
  163 
  164         xdev = to_xenbus_device(dev);
  165         if (xdev == NULL)
  166                 return -ENODEV;
  167 2
  168         /* stuff we want to pass to /sbin/hotplug */
  169         add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
  170                        "XENBUS_TYPE=%s", xdev->devicetype);
  171 
  172         add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
  173                        "XENBUS_PATH=%s", xdev->nodename);
  174 
  175         add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
  176                        "XENBUS_BASE_PATH=%s", xenbus_backend.root);
  177 
  178         /* terminate, set to next free slot, shrink available space */
  179         envp[i] = NULL;
  180         envp = &envp[i];
  181         num_envp -= i;
  182         buffer = &buffer[length];
  183         buffer_size -= length;
  184 
  185         if (dev->driver) {
  186                 drv = to_xenbus_driver(dev->driver);
  187                 if (drv && drv->uevent)
  188                         return drv->uevent(xdev, envp, num_envp, buffer,
  189                                            buffer_size);
  190         }
  191 
  192         return 0;
  193 }
  194 #endif
  195 
  196 int xenbus_register_backend(struct xenbus_driver *drv)
  197 {
  198         drv->read_otherend_details = read_frontend_details;
  199 
  200         return xenbus_register_driver_common(drv, &xenbus_backend);
  201 }
  202 
  203 /* backend/<typename>/<frontend-uuid>/<name> */
  204 static int xenbus_probe_backend_unit(const char *dir,
  205                                      const char *type,
  206                                      const char *name)
  207 {
  208         char *nodename;
  209         int err;
  210 
  211         nodename = kasprintf("%s/%s", dir, name);
  212         if (!nodename)
  213                 return -ENOMEM;
  214 
  215         DPRINTK("%s\n", nodename);
  216 
  217         err = xenbus_probe_node(&xenbus_backend, type, nodename);
  218         kfree(nodename);
  219         return err;
  220 }
  221 
  222 /* backend/<typename>/<frontend-domid> */
  223 static int xenbus_probe_backend(const char *type, const char *domid)
  224 {
  225         char *nodename;
  226         int err = 0;
  227         char **dir;
  228         unsigned int i, dir_n = 0;
  229 
  230         DPRINTK("");
  231 
  232         nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
  233         if (!nodename)
  234                 return -ENOMEM;
  235 
  236         dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n);
  237         if (IS_ERR(dir)) {
  238                 kfree(nodename);
  239                 return PTR_ERR(dir);
  240         }
  241 
  242         for (i = 0; i < dir_n; i++) {
  243                 err = xenbus_probe_backend_unit(nodename, type, dir[i]);
  244                 if (err)
  245                         break;
  246         }
  247         kfree(dir);
  248         kfree(nodename);
  249         return err;
  250 }
  251 
  252 static void backend_changed(struct xenbus_watch *watch,
  253                             const char **vec, unsigned int len)
  254 {
  255         DPRINTK("");
  256 
  257         dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
  258 }
  259 
  260 static struct xenbus_watch be_watch = {
  261         .node = "backend",
  262         .callback = backend_changed,
  263 };
  264 #if 0
  265 void xenbus_backend_suspend(int (*fn)(struct device *, void *))
  266 {
  267         DPRINTK("");
  268         if (!xenbus_backend.error)
  269                 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
  270 }
  271 
  272 void xenbus_backend_resume(int (*fn)(struct device *, void *))
  273 {
  274         DPRINTK("");
  275         if (!xenbus_backend.error)
  276                 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
  277 }
  278 #endif
  279 void xenbus_backend_probe_and_watch(void)
  280 {
  281         xenbus_probe_devices(&xenbus_backend);
  282         register_xenbus_watch(&be_watch);
  283 }
  284 
  285 #if 0
  286 void xenbus_backend_bus_register(void)
  287 {
  288         xenbus_backend.error = bus_register(&xenbus_backend.bus);
  289         if (xenbus_backend.error)
  290                 log(LOG_WARNING,
  291                        "XENBUS: Error registering backend bus: %i\n",
  292                        xenbus_backend.error);
  293 }
  294 
  295 void xenbus_backend_device_register(void)
  296 {
  297         if (xenbus_backend.error)
  298                 return;
  299 
  300         xenbus_backend.error = device_register(&xenbus_backend.dev);
  301         if (xenbus_backend.error) {
  302                 bus_unregister(&xenbus_backend.bus);
  303                 log(LOG_WARNING,
  304                        "XENBUS: Error registering backend device: %i\n",
  305                        xenbus_backend.error);
  306         }
  307 }
  308 #endif

Cache object: af6f7f7ad20ac38ac1980214c091b46b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.