xenbusb.h (181912) | xenbusb.h (185605) |
---|---|
1/****************************************************************************** 2 * Talks to Xen Store to figure out what devices we have. 3 * | 1/****************************************************************************** 2 * Talks to Xen Store to figure out what devices we have. 3 * |
4 * Copyright (C) 2008 Doug Rabson |
|
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 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 --- 18 unchanged lines hidden (view full) --- 30#if 0 31#define DPRINTK(fmt, args...) \ 32 printf("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args) 33#else 34#define DPRINTK(fmt, args...) ((void)0) 35#endif 36 37#include <sys/cdefs.h> | 5 * Copyright (C) 2005 Rusty Russell, IBM Corporation 6 * Copyright (C) 2005 Mike Wray, Hewlett-Packard 7 * Copyright (C) 2005 XenSource Ltd 8 * 9 * This file may be distributed separately from the Linux kernel, or 10 * incorporated into other software packages, subject to the following license: 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a copy --- 18 unchanged lines hidden (view full) --- 31#if 0 32#define DPRINTK(fmt, args...) \ 33 printf("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args) 34#else 35#define DPRINTK(fmt, args...) ((void)0) 36#endif 37 38#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/sys/xen/xenbus/xenbus_probe.c 181912 2008-08-20 09:20:12Z kmacy $"); | 39__FBSDID("$FreeBSD: head/sys/xen/xenbus/xenbus_probe.c 185605 2008-12-04 07:59:05Z kmacy $"); |
39 40#include <sys/param.h> | 40 41#include <sys/param.h> |
41#include <sys/types.h> 42#include <sys/cdefs.h> 43#include <sys/time.h> 44#include <sys/sema.h> 45#include <sys/eventhandler.h> 46#include <sys/errno.h> | 42#include <sys/bus.h> |
47#include <sys/kernel.h> | 43#include <sys/kernel.h> |
44#include <sys/lock.h> |
|
48#include <sys/malloc.h> 49#include <sys/module.h> | 45#include <sys/malloc.h> 46#include <sys/module.h> |
50#include <sys/conf.h> 51#include <sys/systm.h> | 47#include <sys/sysctl.h> |
52#include <sys/syslog.h> | 48#include <sys/syslog.h> |
53#include <sys/proc.h> 54#include <sys/bus.h> | 49#include <sys/systm.h> |
55#include <sys/sx.h> | 50#include <sys/sx.h> |
51#include <sys/taskqueue.h> |
|
56 57#include <machine/xen/xen-os.h> | 52 53#include <machine/xen/xen-os.h> |
58#include <machine/xen/hypervisor.h> 59#include <machine/xen/xenbus.h> 60#include <machine/xen/evtchn.h> | |
61#include <machine/stdarg.h> 62 | 54#include <machine/stdarg.h> 55 |
56#include <xen/gnttab.h> 57#include <xen/xenbus/xenbusvar.h> |
|
63#include <xen/xenbus/xenbus_comms.h> 64 | 58#include <xen/xenbus/xenbus_comms.h> 59 |
65struct xendev_list_head xenbus_device_frontend_list; 66struct xendev_list_head xenbus_device_backend_list; 67static LIST_HEAD(, xenbus_driver) xendrv_list; 68 69extern struct sx xenwatch_mutex; 70 71EVENTHANDLER_DECLARE(xenstore_event, xenstore_event_handler_t); 72static struct eventhandler_list *xenstore_chain; 73device_t xenbus_dev; 74device_t xenbus_backend_dev; 75static MALLOC_DEFINE(M_XENDEV, "xenintrdrv", "xen system device"); 76 77#define streq(a, b) (strcmp((a), (b)) == 0) 78 79static int watch_otherend(struct xenbus_device *dev); 80 81 82/* If something in array of ids matches this device, return it. */ 83static const struct xenbus_device_id * 84match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev) 85{ 86 for (; !streq(arr->devicetype, ""); arr++) { 87 if (streq(arr->devicetype, dev->devicetype)) 88 return arr; 89 } 90 return NULL; 91} 92 93#if 0 94static int xenbus_match(device_t _dev) 95{ 96 struct xenbus_driver *drv; 97 struct xenbus_device *dev; 98 99 dev = device_get_softc(_dev); 100 drv = dev->driver; 101 102 if (!drv->ids) 103 return 0; 104 105 return match_device(drv->ids, to_xenbus_device(_dev)) != NULL; 106} 107#endif 108 109 110/* device/<type>/<id> => <type>-<id> */ 111static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename) 112{ 113 nodename = strchr(nodename, '/'); 114 if (!nodename || strlen(nodename + 1) >= BUS_ID_SIZE) { 115 log(LOG_WARNING, "XENBUS: bad frontend %s\n", nodename); 116 return -EINVAL; 117 } 118 119 strlcpy(bus_id, nodename + 1, BUS_ID_SIZE); 120 if (!strchr(bus_id, '/')) { 121 log(LOG_WARNING, "XENBUS: bus_id %s no slash\n", bus_id); 122 return -EINVAL; 123 } 124 *strchr(bus_id, '/') = '-'; 125 return 0; 126} 127 128 129static void free_otherend_details(struct xenbus_device *dev) 130{ 131 kfree((void*)(uintptr_t)dev->otherend); 132 dev->otherend = NULL; 133} 134 135 136static void free_otherend_watch(struct xenbus_device *dev) 137{ 138 if (dev->otherend_watch.node) { 139 unregister_xenbus_watch(&dev->otherend_watch); 140 kfree(dev->otherend_watch.node); 141 dev->otherend_watch.node = NULL; 142 } 143} 144 145int 146read_otherend_details(struct xenbus_device *xendev, char *id_node, 147 char *path_node) 148{ 149 int err = xenbus_gather(XBT_NIL, xendev->nodename, 150 id_node, "%i", &xendev->otherend_id, 151 path_node, NULL, &xendev->otherend, 152 NULL); 153 if (err) { 154 xenbus_dev_fatal(xendev, err, 155 "reading other end details from %s", 156 xendev->nodename); 157 return err; 158 } 159 if (strlen(xendev->otherend) == 0 || 160 !xenbus_exists(XBT_NIL, xendev->otherend, "")) { 161 xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s", 162 xendev->nodename); 163 kfree((void *)(uintptr_t)xendev->otherend); 164 xendev->otherend = NULL; 165 return -ENOENT; 166 } 167 168 return 0; 169} 170 171 172static int read_backend_details(struct xenbus_device *xendev) 173{ 174 return read_otherend_details(xendev, "backend-id", "backend"); 175} 176 177#ifdef notyet 178/* XXX - move to probe backend */ 179static int read_frontend_details(struct xenbus_device *xendev) 180{ 181 if (strncmp(xendev->nodename, "backend", 7)) 182 return -ENOENT; 183 return read_otherend_details(xendev, "frontend-id", "frontend"); 184} 185#endif 186 187/* Bus type for frontend drivers. */ 188static int xenbus_probe_frontend(const char *type, const char *name); 189static struct xen_bus_type xenbus_frontend = { 190 .root = "device", 191 .levels = 2, /* device/type/<id> */ 192 .get_bus_id = frontend_bus_id, 193 .probe = xenbus_probe_frontend, 194 .bus = &xenbus_device_frontend_list, 195#if 0 196 /* this initialization needs to happen dynamically */ 197 .bus = { 198 .name = "xen", 199 .match = xenbus_match, 200 }, 201 .dev = { 202 .bus_id = "xen", 203 }, 204#endif | 60struct xenbus_softc { 61 struct xenbus_watch xs_devicewatch; 62 struct task xs_probechildren; 63 struct intr_config_hook xs_attachcb; 64 device_t xs_dev; |
205}; 206 | 65}; 66 |
207#if 0 208static int xenbus_hotplug_backend(device_t dev, char **envp, 209 int num_envp, char *buffer, int buffer_size) 210{ 211 panic("implement me"); 212#if 0 213 struct xenbus_device *xdev; 214 struct xenbus_driver *drv = NULL; 215 int i = 0; 216 int length = 0; 217 char *basepath_end; 218 char *frontend_id; 219 220 DPRINTK(""); 221 222 if (dev == NULL) 223 return -ENODEV; 224 225 xdev = to_xenbus_device(dev); 226 if (xdev == NULL) 227 return -ENODEV; 228 229 if (dev->driver) 230 drv = to_xenbus_driver(dev->driver); 231 232 /* stuff we want to pass to /sbin/hotplug */ 233 add_hotplug_env_var(envp, num_envp, &i, 234 buffer, buffer_size, &length, 235 "XENBUS_TYPE=%s", xdev->devicetype); 236 237 add_hotplug_env_var(envp, num_envp, &i, 238 buffer, buffer_size, &length, 239 "XENBUS_PATH=%s", xdev->nodename); 240 241 add_hotplug_env_var(envp, num_envp, &i, 242 buffer, buffer_size, &length, 243 "XENBUS_BASE_PATH=%s", xdev->nodename); 244 245 basepath_end = strrchr(envp[i - 1], '/'); 246 length -= strlen(basepath_end); 247 *basepath_end = '\0'; 248 basepath_end = strrchr(envp[i - 1], '/'); 249 length -= strlen(basepath_end); 250 *basepath_end = '\0'; 251 252 basepath_end++; 253 frontend_id = kmalloc(strlen(basepath_end) + 1, GFP_KERNEL); 254 strcpy(frontend_id, basepath_end); 255 add_hotplug_env_var(envp, num_envp, &i, 256 buffer, buffer_size, &length, 257 "XENBUS_FRONTEND_ID=%s", frontend_id); 258 kfree(frontend_id); 259 260 /* terminate, set to next free slot, shrink available space */ 261 envp[i] = NULL; 262 envp = &envp[i]; 263 num_envp -= i; 264 buffer = &buffer[length]; 265 buffer_size -= length; 266 267 if (drv && drv->hotplug) 268 return drv->hotplug(xdev, envp, num_envp, buffer, buffer_size); 269 270#endif 271 return 0; 272} 273#endif 274 275#if 0 276static int xenbus_probe_backend(const char *type, const char *domid, int unit); 277static struct xen_bus_type xenbus_backend = { 278 .root = "backend", 279 .levels = 3, /* backend/type/<frontend>/<id> */ 280 .get_bus_id = backend_bus_id, 281 .probe = xenbus_probe_backend, 282 /* at init time */ 283 .bus = &xenbus_device_backend_list, 284#if 0 285 .bus = { 286 .name = "xen-backend", 287 .match = xenbus_match, 288 .hotplug = xenbus_hotplug_backend, 289 }, 290 .dev = { 291 .bus_id = "xen-backend", 292 }, 293#endif | 67struct xenbus_device_ivars { 68 struct xenbus_watch xd_otherend_watch; /* must be first */ 69 struct sx xd_lock; 70 device_t xd_dev; 71 char *xd_node; /* node name in xenstore */ 72 char *xd_type; /* xen device type */ 73 enum xenbus_state xd_state; 74 int xd_otherend_id; 75 char *xd_otherend_path; |
294}; | 76}; |
295#endif | |
296 | 77 |
297static void otherend_changed(struct xenbus_watch *watch, 298 const char **vec, unsigned int len) | 78/* Simplified asprintf. */ 79char * 80kasprintf(const char *fmt, ...) |
299{ | 81{ |
82 va_list ap; 83 unsigned int len; 84 char *p, dummy[1]; |
|
300 | 85 |
301 struct xenbus_device *dev = (struct xenbus_device *)watch; 302 struct xenbus_driver *drv = dev->driver; 303 XenbusState state; 304 305 /* Protect us against watches firing on old details when the otherend 306 details change, say immediately after a resume. */ 307 if (!dev->otherend || strncmp(dev->otherend, vec[XS_WATCH_PATH], 308 strlen(dev->otherend))) { 309 DPRINTK("Ignoring watch at %s", vec[XS_WATCH_PATH]); 310 return; 311 } | 86 va_start(ap, fmt); 87 /* FIXME: vsnprintf has a bug, NULL should work */ 88 len = vsnprintf(dummy, 0, fmt, ap); 89 va_end(ap); |
312 | 90 |
313 state = xenbus_read_driver_state(dev->otherend); 314 315 DPRINTK("state is %d, %s, %s", state, dev->otherend_watch.node, 316 vec[XS_WATCH_PATH]); 317 318 /* 319 * Ignore xenbus transitions during shutdown. This prevents us doing 320 * work that can fail e.g., when the rootfs is gone. 321 */ 322#if 0 323 if (system_state > SYSTEM_RUNNING) { 324 struct xen_bus_type *bus = bus; 325 bus = container_of(dev->dev.bus, struct xen_bus_type, bus); 326 /* If we're frontend, drive the state machine to Closed. */ 327 /* This should cause the backend to release our resources. */ 328 if ((bus == &xenbus_frontend) && (state == XenbusStateClosing)) 329 xenbus_frontend_closed(dev); 330 return; 331 } 332#endif 333 if (drv->otherend_changed) 334 drv->otherend_changed(dev, state); 335 | 91 p = kmalloc(len + 1, GFP_KERNEL); 92 if (!p) 93 return NULL; 94 va_start(ap, fmt); 95 vsprintf(p, fmt, ap); 96 va_end(ap); 97 return p; |
336} 337 | 98} 99 |
338 339static int talk_to_otherend(struct xenbus_device *dev) | 100static void 101xenbus_identify(driver_t *driver, device_t parent) |
340{ | 102{ |
341 struct xenbus_driver *drv; | |
342 | 103 |
343 drv = dev->driver; 344 345 free_otherend_watch(dev); 346 free_otherend_details(dev); 347 348 return drv->read_otherend_details(dev); | 104 BUS_ADD_CHILD(parent, 0, "xenbus", 0); |
349} 350 | 105} 106 |
351static int watch_otherend(struct xenbus_device *dev) 352{ 353 return xenbus_watch_path2(dev, dev->otherend, "state", 354 &dev->otherend_watch, otherend_changed); 355} 356 | |
357static int | 107static int |
358xenbus_dev_probe(struct xenbus_device *dev) | 108xenbus_probe(device_t dev) |
359{ | 109{ |
360 struct xenbus_driver *drv = dev->driver; 361 const struct xenbus_device_id *id; 362 int err; 363 | 110 int err = 0; 111 |
364 DPRINTK(""); | 112 DPRINTK(""); |
365 366 if (!drv->probe) { 367 err = -ENODEV; 368 goto fail; 369 } 370 371 id = match_device(drv->ids, dev); 372 if (!id) { 373 err = -ENODEV; 374 goto fail; 375 } 376 377 err = talk_to_otherend(dev); | 113 114 /* Initialize the interface to xenstore. */ 115 err = xs_init(); |
378 if (err) { | 116 if (err) { |
379 log(LOG_WARNING, 380 "xenbus_probe: talk_to_otherend on %s failed.\n", 381 dev->nodename); 382 return err; | 117 log(LOG_WARNING, 118 "XENBUS: Error initializing xenstore comms: %i\n", err); 119 return (ENXIO); |
383 } | 120 } |
384 385 err = drv->probe(dev, id); 386 if (err) 387 goto fail; 388 389 err = watch_otherend(dev); | 121 err = gnttab_init(); |
390 if (err) { | 122 if (err) { |
391 log(LOG_WARNING, 392 "xenbus_probe: watch_otherend on %s failed.\n", 393 dev->nodename); 394 return err; | 123 log(LOG_WARNING, 124 "XENBUS: Error initializing grant table: %i\n", err); 125 return (ENXIO); |
395 } | 126 } |
396 397 return 0; 398 fail: 399 xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename); 400 xenbus_switch_state(dev, XenbusStateClosed); 401 return -ENODEV; 402} | 127 device_set_desc(dev, "Xen Devices"); |
403 | 128 |
404static void xenbus_dev_free(struct xenbus_device *xendev) 405{ 406 LIST_REMOVE(xendev, list); 407 kfree(xendev); | 129 return (0); |
408} 409 | 130} 131 |
410int 411xenbus_remove_device(struct xenbus_device *dev) | 132static enum xenbus_state 133xenbus_otherend_state(struct xenbus_device_ivars *ivars) |
412{ | 134{ |
413 struct xenbus_driver *drv = dev->driver; | |
414 | 135 |
415 DPRINTK(""); 416 417 free_otherend_watch(dev); 418 free_otherend_details(dev); 419 420 if (drv->remove) 421 drv->remove(dev); 422 423 xenbus_switch_state(dev, XenbusStateClosed); 424 425 if (drv->cleanup_device) 426 return drv->cleanup_device(dev); 427 428 xenbus_dev_free(dev); 429 430 return 0; | 136 return (xenbus_read_driver_state(ivars->xd_otherend_path)); |
431} 432 | 137} 138 |
433#if 0 434static int 435xenbus_dev_remove(device_t _dev) | 139static void 140xenbus_backend_changed(struct xenbus_watch *watch, const char **vec, 141 unsigned int len) |
436{ | 142{ |
437 return xenbus_remove_device(to_xenbus_device(_dev)); 438} 439#endif | 143 struct xenbus_device_ivars *ivars; 144 device_t dev; 145 enum xenbus_state newstate; |
440 | 146 |
441int xenbus_register_driver_common(struct xenbus_driver *drv, 442 struct xen_bus_type *bus) 443{ 444 struct xenbus_device *xdev; 445 446#if 0 447 int ret; 448 /* this all happens in the driver itself 449 * doing this here simple serves to obfuscate 450 */ | 147 ivars = (struct xenbus_device_ivars *) watch; 148 dev = ivars->xd_dev; |
451 | 149 |
452 drv->driver.name = drv->name; 453 drv->driver.bus = &bus->bus; 454 drv->driver.owner = drv->owner; 455 drv->driver.probe = xenbus_dev_probe; 456 drv->driver.remove = xenbus_dev_remove; | 150 if (!ivars->xd_otherend_path 151 || strncmp(ivars->xd_otherend_path, vec[XS_WATCH_PATH], 152 strlen(ivars->xd_otherend_path))) 153 return; |
457 | 154 |
458 return ret; 459#endif 460 sx_xlock(&xenwatch_mutex); 461 LIST_INSERT_HEAD(&xendrv_list, drv, list); 462 sx_xunlock(&xenwatch_mutex); 463 LIST_FOREACH(xdev, bus->bus, list) { 464 if (match_device(drv->ids, xdev)) { 465 xdev->driver = drv; 466 xenbus_dev_probe(xdev); 467 } 468 } 469 return 0; | 155 newstate = xenbus_otherend_state(ivars); 156 XENBUS_BACKEND_CHANGED(dev, newstate); |
470} 471 | 157} 158 |
472int xenbus_register_frontend(struct xenbus_driver *drv) | 159static int 160xenbus_device_exists(device_t dev, const char *node) |
473{ | 161{ |
474 drv->read_otherend_details = read_backend_details; | 162 device_t *kids; 163 struct xenbus_device_ivars *ivars; 164 int i, count, result; |
475 | 165 |
476 return xenbus_register_driver_common(drv, &xenbus_frontend); 477} 478EXPORT_SYMBOL(xenbus_register_frontend); | 166 if (device_get_children(dev, &kids, &count)) 167 return (FALSE); |
479 | 168 |
480 481void xenbus_unregister_driver(struct xenbus_driver *drv) 482{ 483#if 0 484 driver_unregister(&drv->driver); 485#endif 486} 487EXPORT_SYMBOL(xenbus_unregister_driver); 488 489struct xb_find_info 490{ 491 struct xenbus_device *dev; 492 const char *nodename; 493}; 494 495static struct xenbus_device * 496xenbus_device_find(const char *nodename, struct xendev_list_head *bus) 497{ 498 struct xenbus_device *xdev; 499 LIST_FOREACH(xdev, bus, list) { 500 if (streq(xdev->nodename, nodename)) { 501 return xdev; 502#if 0 503 get_device(dev); 504#endif | 169 result = FALSE; 170 for (i = 0; i < count; i++) { 171 ivars = device_get_ivars(kids[i]); 172 if (!strcmp(ivars->xd_node, node)) { 173 result = TRUE; 174 break; |
505 } 506 } | 175 } 176 } |
507 return NULL; 508} 509#if 0 510static int cleanup_dev(device_t dev, void *data) 511{ 512 struct xenbus_device *xendev = device_get_softc(dev); 513 struct xb_find_info *info = data; 514 int len = strlen(info->nodename); | 177 free(kids, M_TEMP); |
515 | 178 |
516 DPRINTK("%s", info->nodename); 517 518 if (!strncmp(xendev->nodename, info->nodename, len)) { 519 info->dev = xendev; 520#if 0 521 get_device(dev); 522#endif 523 return 1; 524 } 525 return 0; | 179 return (result); |
526} 527 | 180} 181 |
528#endif 529static void xenbus_cleanup_devices(const char *path, struct xendev_list_head * bus) | 182static int 183xenbus_add_device(device_t dev, const char *bus, 184 const char *type, const char *id) |
530{ | 185{ |
531#if 0 532 struct xb_find_info info = { .nodename = path }; | 186 device_t child; 187 struct xenbus_device_ivars *ivars; 188 enum xenbus_state state; 189 char *statepath; |
533 | 190 |
534 do { 535 info.dev = NULL; 536 bus_for_each_dev(bus, NULL, &info, cleanup_dev); 537 if (info.dev) { 538 device_unregister(&info.dev->dev); 539 put_device(&info.dev->dev); 540 } 541 } while (info.dev); 542#endif 543} | 191 ivars = malloc(sizeof(struct xenbus_device_ivars), 192 M_DEVBUF, M_ZERO|M_WAITOK); 193 ivars->xd_node = kasprintf("%s/%s/%s", bus, type, id); |
544 | 194 |
545#if 0 546void xenbus_dev_release(device_t dev) 547{ 548 /* 549 * nothing to do softc gets freed with the device 550 */ 551 552} 553#endif 554/* Simplified asprintf. */ 555char *kasprintf(const char *fmt, ...) 556{ 557 va_list ap; 558 unsigned int len; 559 char *p, dummy[1]; | 195 if (xenbus_device_exists(dev, ivars->xd_node)) { 196 /* 197 * We are already tracking this node 198 */ 199 free(ivars->xd_node, M_DEVBUF); 200 free(ivars, M_DEVBUF); 201 return (0); 202 } |
560 | 203 |
561 va_start(ap, fmt); 562 /* FIXME: vsnprintf has a bug, NULL should work */ 563 len = vsnprintf(dummy, 0, fmt, ap); 564 va_end(ap); | 204 state = xenbus_read_driver_state(ivars->xd_node); |
565 | 205 |
566 p = kmalloc(len + 1, GFP_KERNEL); 567 if (!p) 568 return NULL; 569 va_start(ap, fmt); 570 vsprintf(p, fmt, ap); 571 va_end(ap); 572 return p; 573} 574 575#if 0 576static ssize_t xendev_show_nodename(struct device *dev, char *buf) 577{ 578 return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename); 579} 580DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL); 581 582static ssize_t xendev_show_devtype(struct device *dev, char *buf) 583{ 584 return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype); 585} 586DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL); 587#endif 588 589int xenbus_probe_node(struct xen_bus_type *bus, const char *type, 590 const char *nodename) 591{ 592#define CHECK_FAIL \ 593 do { \ 594 if (err) \ 595 goto fail; \ 596 } while (0) \ 597 598 599 600 int err; 601 struct xenbus_device *xendev; 602 struct xenbus_driver *xdrv; 603 size_t stringlen; 604 char *tmpstring; 605 606 XenbusState state = xenbus_read_driver_state(nodename); 607 608 if (bus->error) 609 return (bus->error); 610 611 | |
612 if (state != XenbusStateInitialising) { | 206 if (state != XenbusStateInitialising) { |
613 /* Device is not new, so ignore it. This can happen if a 614 device is going away after switching to Closed. */ 615 return 0; | 207 /* 208 * Device is not new, so ignore it. This can 209 * happen if a device is going away after 210 * switching to Closed. 211 */ 212 free(ivars->xd_node, M_DEVBUF); 213 free(ivars, M_DEVBUF); 214 return (0); |
616 } | 215 } |
617 618 stringlen = strlen(nodename) + 1 + strlen(type) + 1; 619 xendev = kmalloc(sizeof(*xendev) + stringlen, GFP_KERNEL); 620 if (!xendev) 621 return -ENOMEM; 622 memset(xendev, 0, sizeof(*xendev)); 623 xendev->state = XenbusStateInitialising; 624 625 /* Copy the strings into the extra space. */ 626 627 tmpstring = (char *)(xendev + 1); 628 strcpy(tmpstring, nodename); 629 xendev->nodename = tmpstring; 630 631 tmpstring += strlen(tmpstring) + 1; 632 strcpy(tmpstring, type); 633 xendev->devicetype = tmpstring; | 216 |
634 /* | 217 /* |
635 * equivalent to device registration 636 * events | 218 * Find the backend details |
637 */ | 219 */ |
638 LIST_INSERT_HEAD(bus->bus, xendev, list); 639 LIST_FOREACH(xdrv, &xendrv_list, list) { 640 if (match_device(xdrv->ids, xendev)) { 641 xendev->driver = xdrv; 642 if (!xenbus_dev_probe(xendev)) 643 break; 644 } 645 } | 220 xenbus_gather(XBT_NIL, ivars->xd_node, 221 "backend-id", "%i", &ivars->xd_otherend_id, 222 "backend", NULL, &ivars->xd_otherend_path, 223 NULL); |
646 | 224 |
647#if 0 648 xendev->dev.parent = &bus->dev; 649 xendev->dev.bus = &bus->bus; 650 xendev->dev.release = xenbus_dev_release; 651 652 err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename); 653 CHECK_FAIL; 654 655 /* Register with generic device framework. */ 656 err = device_register(&xendev->dev); 657 CHECK_FAIL; 658 659 device_create_file(&xendev->dev, &dev_attr_nodename); 660 device_create_file(&xendev->dev, &dev_attr_devtype); 661#endif 662 return 0; 663 664#undef CHECK_FAIL 665#if 0 666 fail: 667 xenbus_dev_free(xendev); 668#endif 669 return err; 670} | 225 sx_init(&ivars->xd_lock, "xdlock"); 226 ivars->xd_type = strdup(type, M_DEVBUF); 227 ivars->xd_state = XenbusStateInitialising; |
671 | 228 |
672/* device/<typename>/<name> */ 673static int xenbus_probe_frontend(const char *type, const char *name) 674{ 675 char *nodename; 676 int err; | 229 statepath = malloc(strlen(ivars->xd_otherend_path) 230 + strlen("/state") + 1, M_DEVBUF, M_NOWAIT); 231 sprintf(statepath, "%s/state", ivars->xd_otherend_path); |
677 | 232 |
678 nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name); 679 if (!nodename) 680 return -ENOMEM; | 233 ivars->xd_otherend_watch.node = statepath; 234 ivars->xd_otherend_watch.callback = xenbus_backend_changed; |
681 | 235 |
682 DPRINTK("%s", nodename); | 236 child = device_add_child(dev, NULL, -1); 237 ivars->xd_dev = child; 238 device_set_ivars(child, ivars); |
683 | 239 |
684 err = xenbus_probe_node(&xenbus_frontend, type, nodename); 685 kfree(nodename); 686 return err; | 240 return (0); |
687} 688 | 241} 242 |
689static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type) | 243static int 244xenbus_enumerate_type(device_t dev, const char *bus, const char *type) |
690{ | 245{ |
691 int err = 0; | |
692 char **dir; | 246 char **dir; |
693 unsigned int dir_n = 0; 694 int i; | 247 unsigned int i, count; |
695 | 248 |
696 dir = xenbus_directory(XBT_NIL, bus->root, type, &dir_n); | 249 dir = xenbus_directory(XBT_NIL, bus, type, &count); |
697 if (IS_ERR(dir)) | 250 if (IS_ERR(dir)) |
698 return PTR_ERR(dir); | 251 return (EINVAL); 252 for (i = 0; i < count; i++) 253 xenbus_add_device(dev, bus, type, dir[i]); |
699 | 254 |
700 for (i = 0; i < dir_n; i++) { 701 err = bus->probe(type, dir[i]); 702 if (err) 703 break; 704 } 705 kfree(dir); 706 return err; | 255 free(dir, M_DEVBUF); 256 257 return (0); |
707} 708 | 258} 259 |
709int xenbus_probe_devices(struct xen_bus_type *bus) | 260static int 261xenbus_enumerate_bus(device_t dev, const char *bus) |
710{ | 262{ |
711 int err = 0; | |
712 char **dir; | 263 char **dir; |
713 unsigned int i, dir_n; | 264 unsigned int i, count; |
714 | 265 |
715 dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n); | 266 dir = xenbus_directory(XBT_NIL, bus, "", &count); |
716 if (IS_ERR(dir)) | 267 if (IS_ERR(dir)) |
717 return PTR_ERR(dir); 718 719 for (i = 0; i < dir_n; i++) { 720 err = xenbus_probe_device_type(bus, dir[i]); 721 if (err) 722 break; | 268 return (EINVAL); 269 for (i = 0; i < count; i++) { 270 xenbus_enumerate_type(dev, bus, dir[i]); |
723 } | 271 } |
724 kfree(dir); | 272 free(dir, M_DEVBUF); |
725 | 273 |
726 return err; | 274 return (0); |
727} 728 | 275} 276 |
729static unsigned int char_count(const char *str, char c) | 277static int 278xenbus_probe_children(device_t dev) |
730{ | 279{ |
731 unsigned int i, ret = 0; | 280 device_t *kids; 281 struct xenbus_device_ivars *ivars; 282 int i, count; |
732 | 283 |
733 for (i = 0; str[i]; i++) 734 if (str[i] == c) 735 ret++; 736 return ret; 737} | 284 /* 285 * Probe any new devices and register watches for any that 286 * attach successfully. Since part of the protocol which 287 * establishes a connection with the other end is interrupt 288 * driven, we sleep until the device reaches a stable state 289 * (closed or connected). 290 */ 291 if (device_get_children(dev, &kids, &count) == 0) { 292 for (i = 0; i < count; i++) { 293 if (device_get_state(kids[i]) != DS_NOTPRESENT) 294 continue; |
738 | 295 |
739static int strsep_len(const char *str, char c, unsigned int len) 740{ 741 unsigned int i; 742 743 for (i = 0; str[i]; i++) 744 if (str[i] == c) { 745 if (len == 0) 746 return i; 747 len--; | 296 if (device_probe_and_attach(kids[i])) 297 continue; 298 ivars = device_get_ivars(kids[i]); 299 register_xenbus_watch( 300 &ivars->xd_otherend_watch); 301 sx_xlock(&ivars->xd_lock); 302 while (ivars->xd_state != XenbusStateClosed 303 && ivars->xd_state != XenbusStateConnected) 304 sx_sleep(&ivars->xd_state, &ivars->xd_lock, 305 0, "xdattach", 0); 306 sx_xunlock(&ivars->xd_lock); |
748 } | 307 } |
749 return (len == 0) ? i : -ERANGE; 750} 751 752void dev_changed(const char *node, struct xen_bus_type *bus) 753{ 754 int exists, rootlen; 755 struct xenbus_device *dev; 756 char type[BUS_ID_SIZE]; 757 const char *p; 758 char *root; 759 760 DPRINTK(""); 761 if (char_count(node, '/') < 2) 762 return; 763 764 exists = xenbus_exists(XBT_NIL, node, ""); 765 if (!exists) { 766 xenbus_cleanup_devices(node, bus->bus); 767 return; | 308 free(kids, M_TEMP); |
768 } 769 | 309 } 310 |
770 /* backend/<type>/... or device/<type>/... */ 771 p = strchr(node, '/') + 1; 772 snprintf(type, BUS_ID_SIZE, "%.*s", (int)strcspn(p, "/"), p); 773 type[BUS_ID_SIZE-1] = '\0'; 774 775 rootlen = strsep_len(node, '/', bus->levels); 776 if (rootlen < 0) 777 return; 778 root = kasprintf("%.*s", rootlen, node); 779 if (!root) 780 return; 781 782 dev = xenbus_device_find(root, bus->bus); 783 if (!dev) 784 xenbus_probe_node(bus, type, root); 785#if 0 786 else 787 put_device(&dev->dev); 788#endif 789 kfree(root); | 311 return (0); |
790} 791 | 312} 313 |
792static void frontend_changed(struct xenbus_watch *watch, 793 const char **vec, unsigned int len) | 314static void 315xenbus_probe_children_cb(void *arg, int pending) |
794{ | 316{ |
795 DPRINTK(""); | 317 device_t dev = (device_t) arg; |
796 | 318 |
797 dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend); | 319 xenbus_probe_children(dev); |
798} 799 | 320} 321 |
800/* We watch for devices appearing and vanishing. */ 801static struct xenbus_watch fe_watch = { 802 .node = "device", 803 .callback = frontend_changed, 804}; 805 806#ifdef notyet 807 808static int suspend_dev(device_t dev, void *data) | 322static void 323xenbus_devices_changed(struct xenbus_watch *watch, 324 const char **vec, unsigned int len) |
809{ | 325{ |
810 int err = 0; 811 struct xenbus_driver *drv; 812 struct xenbus_device *xdev; | 326 struct xenbus_softc *sc = (struct xenbus_softc *) watch; 327 device_t dev = sc->xs_dev; 328 char *node, *bus, *type, *id, *p; |
813 | 329 |
814 DPRINTK(""); | 330 node = strdup(vec[XS_WATCH_PATH], M_DEVBUF);; 331 p = strchr(node, '/'); 332 if (!p) 333 goto out; 334 bus = node; 335 *p = 0; 336 type = p + 1; |
815 | 337 |
816 xdev = device_get_softc(dev); | 338 p = strchr(type, '/'); 339 if (!p) 340 goto out; 341 *p = 0; 342 id = p + 1; |
817 | 343 |
818 drv = xdev->driver; | 344 p = strchr(id, '/'); 345 if (p) 346 *p = 0; |
819 | 347 |
820 if (device_get_driver(dev) == NULL) 821 return 0; 822 823 if (drv->suspend) 824 err = drv->suspend(xdev); 825#if 0 826 /* bus_id ? */ 827 if (err) 828 log(LOG_WARNING, "xenbus: suspend %s failed: %i\n", 829 dev->bus_id, err); 830#endif 831 return 0; | 348 xenbus_add_device(dev, bus, type, id); 349 taskqueue_enqueue(taskqueue_thread, &sc->xs_probechildren); 350out: 351 free(node, M_DEVBUF); |
832} 833 | 352} 353 |
354static void 355xenbus_attach_deferred(void *arg) 356{ 357 device_t dev = (device_t) arg; 358 struct xenbus_softc *sc = device_get_softc(dev); 359 int error; 360 361 error = xenbus_enumerate_bus(dev, "device"); 362 if (error) 363 return; 364 xenbus_probe_children(dev); |
|
834 | 365 |
366 sc->xs_dev = dev; 367 sc->xs_devicewatch.node = "device"; 368 sc->xs_devicewatch.callback = xenbus_devices_changed; |
|
835 | 369 |
836static int resume_dev(device_t dev, void *data) 837{ 838 int err; 839 struct xenbus_driver *drv; 840 struct xenbus_device *xdev; | 370 TASK_INIT(&sc->xs_probechildren, 0, xenbus_probe_children_cb, dev); |
841 | 371 |
842 DPRINTK(""); | 372 register_xenbus_watch(&sc->xs_devicewatch); |
843 | 373 |
844 if (device_get_driver(dev) == NULL) 845 return 0; 846 xdev = device_get_softc(dev); 847 drv = xdev->driver; | 374 config_intrhook_disestablish(&sc->xs_attachcb); 375} |
848 | 376 |
849 err = talk_to_otherend(xdev); 850#if 0 851 if (err) { 852 log(LOG_WARNING, 853 "xenbus: resume (talk_to_otherend) %s failed: %i\n", 854 dev->bus_id, err); 855 return err; 856 } 857#endif 858 if (drv->resume) 859 err = drv->resume(xdev); | 377static int 378xenbus_attach(device_t dev) 379{ 380 struct xenbus_softc *sc = device_get_softc(dev); |
860 | 381 |
861 err = watch_otherend(xdev); 862#if 0 863 /* bus_id? */ 864 if (err) 865 log(LOG_WARNING, 866 "xenbus: resume %s failed: %i\n", dev->bus_id, err); 867#endif 868 return err; | 382 sc->xs_attachcb.ich_func = xenbus_attach_deferred; 383 sc->xs_attachcb.ich_arg = dev; 384 config_intrhook_establish(&sc->xs_attachcb); 385 386 return (0); |
869} 870 | 387} 388 |
871#endif 872void xenbus_suspend(void) | 389static void 390xenbus_suspend(device_t dev) |
873{ 874 DPRINTK(""); 875 panic("implement me"); 876#if 0 877 bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev); 878 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev); 879#endif 880 xs_suspend(); 881} | 391{ 392 DPRINTK(""); 393 panic("implement me"); 394#if 0 395 bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev); 396 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev); 397#endif 398 xs_suspend(); 399} |
882EXPORT_SYMBOL(xenbus_suspend); | |
883 | 400 |
884void xenbus_resume(void) | 401static void 402xenbus_resume(device_t dev) |
885{ 886 xb_init_comms(); 887 xs_resume(); 888 panic("implement me"); 889#if 0 890 bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev); 891 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev); 892#endif 893} | 403{ 404 xb_init_comms(); 405 xs_resume(); 406 panic("implement me"); 407#if 0 408 bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev); 409 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev); 410#endif 411} |
894EXPORT_SYMBOL(xenbus_resume); | |
895 | 412 |
896#if 0 897static device_t 898xenbus_add_child(device_t bus, int order, const char *name, int unit) 899{ 900 device_t child; 901 902 child = device_add_child_ordered(bus, order, name, unit); 903 904 return(child); 905} 906#endif 907 908/* A flag to determine if xenstored is 'ready' (i.e. has started) */ 909int xenstored_ready = 0; 910 911 912int register_xenstore_notifier(xenstore_event_handler_t func, void *arg, int priority) | 413static int 414xenbus_print_child(device_t dev, device_t child) |
913{ | 415{ |
914 int ret = 0; | 416 struct xenbus_device_ivars *ivars = device_get_ivars(child); 417 int retval = 0; |
915 | 418 |
916 if (xenstored_ready > 0) 917 ret = func(NULL); 918 else 919 eventhandler_register(xenstore_chain, "xenstore", func, arg, priority); | 419 retval += bus_print_child_header(dev, child); 420 retval += printf(" at %s", ivars->xd_node); 421 retval += bus_print_child_footer(dev, child); |
920 | 422 |
921 return ret; | 423 return (retval); |
922} | 424} |
923EXPORT_SYMBOL(register_xenstore_notifier); 924#if 0 925void unregister_xenstore_notifier(struct notifier_block *nb) | 425 426static int 427xenbus_read_ivar(device_t dev, device_t child, int index, 428 uintptr_t * result) |
926{ | 429{ |
927 notifier_chain_unregister(&xenstore_chain, nb); 928} 929EXPORT_SYMBOL(unregister_xenstore_notifier); 930#endif | 430 struct xenbus_device_ivars *ivars = device_get_ivars(child); |
931 | 431 |
432 switch (index) { 433 case XENBUS_IVAR_NODE: 434 *result = (uintptr_t) ivars->xd_node; 435 return (0); 436 case XENBUS_IVAR_TYPE: 437 *result = (uintptr_t) ivars->xd_type; 438 return (0); 439 case XENBUS_IVAR_STATE: 440 *result = (uintptr_t) ivars->xd_state; 441 return (0); |
|
932 | 442 |
443 case XENBUS_IVAR_OTHEREND_ID: 444 *result = (uintptr_t) ivars->xd_otherend_id; 445 return (0); |
|
933 | 446 |
934#ifdef DOM0 935static struct proc_dir_entry *xsd_mfn_intf; 936static struct proc_dir_entry *xsd_port_intf; | 447 case XENBUS_IVAR_OTHEREND_PATH: 448 *result = (uintptr_t) ivars->xd_otherend_path; 449 return (0); 450 } |
937 | 451 |
938 939static int xsd_mfn_read(char *page, char **start, off_t off, 940 int count, int *eof, void *data) 941{ 942 int len; 943 len = sprintf(page, "%ld", xen_start_info->store_mfn); 944 *eof = 1; 945 return len; | 452 return (ENOENT); |
946} 947 | 453} 454 |
948static int xsd_port_read(char *page, char **start, off_t off, 949 int count, int *eof, void *data) | 455static int 456xenbus_write_ivar(device_t dev, device_t child, int index, uintptr_t value) |
950{ | 457{ |
951 int len; | 458 struct xenbus_device_ivars *ivars = device_get_ivars(child); 459 enum xenbus_state newstate; 460 int currstate; 461 int error; |
952 | 462 |
953 len = sprintf(page, "%d", xen_start_info->store_evtchn); 954 *eof = 1; 955 return len; 956} | 463 switch (index) { 464 case XENBUS_IVAR_STATE: 465 newstate = (enum xenbus_state) value; 466 sx_xlock(&ivars->xd_lock); 467 if (ivars->xd_state == newstate) 468 goto out; |
957 | 469 |
958#endif | 470 error = xenbus_scanf(XBT_NIL, ivars->xd_node, "state", 471 "%d", &currstate); 472 if (error < 0) 473 goto out; |
959 | 474 |
960static int dom0 = 0; | 475 error = xenbus_printf(XBT_NIL, ivars->xd_node, "state", 476 "%d", newstate); 477 if (error) { 478 if (newstate != XenbusStateClosing) /* Avoid looping */ 479 xenbus_dev_fatal(dev, error, "writing new state"); 480 goto out; 481 } 482 ivars->xd_state = newstate; 483 wakeup(&ivars->xd_state); 484 out: 485 sx_xunlock(&ivars->xd_lock); 486 return (0); |
961 | 487 |
962static int 963xenbus_probe_sysinit(void *unused) 964{ 965 int err = 0; 966 967 DPRINTK(""); 968 969 LIST_INIT(&xenbus_device_frontend_list); 970 LIST_INIT(&xenbus_device_backend_list); 971 LIST_INIT(&xendrv_list); 972#if 0 973 if (xen_init() < 0) { 974 DPRINTK("failed"); 975 return -ENODEV; | 488 case XENBUS_IVAR_NODE: 489 case XENBUS_IVAR_TYPE: 490 case XENBUS_IVAR_OTHEREND_ID: 491 case XENBUS_IVAR_OTHEREND_PATH: 492 /* 493 * These variables are read-only. 494 */ 495 return (EINVAL); |
976 } | 496 } |
977 978 979 /* Register ourselves with the kernel bus & device subsystems */ 980 bus_register(&xenbus_frontend.bus); 981 bus_register(&xenbus_backend.bus); 982 device_register(&xenbus_frontend.dev); 983 device_register(&xenbus_backend.dev); 984#endif 985 986 /* 987 ** Domain0 doesn't have a store_evtchn or store_mfn yet. 988 */ 989 dom0 = (xen_start_info->store_evtchn == 0); 990 991 992#ifdef DOM0 993 if (dom0) { 994 995 unsigned long page; 996 evtchn_op_t op = { 0 }; 997 int ret; 998 999 1000 /* Allocate page. */ 1001 page = get_zeroed_page(GFP_KERNEL); 1002 if (!page) 1003 return -ENOMEM; 1004 1005 /* We don't refcnt properly, so set reserved on page. 1006 * (this allocation is permanent) */ 1007 SetPageReserved(virt_to_page(page)); 1008 1009 xen_start_info->store_mfn = 1010 pfn_to_mfn(virt_to_phys((void *)page) >> 1011 PAGE_SHIFT); 1012 1013 /* Next allocate a local port which xenstored can bind to */ 1014 op.cmd = EVTCHNOP_alloc_unbound; 1015 op.u.alloc_unbound.dom = DOMID_SELF; 1016 op.u.alloc_unbound.remote_dom = 0; 1017 1018 ret = HYPERVISOR_event_channel_op(&op); 1019 BUG_ON(ret); 1020 xen_start_info->store_evtchn = op.u.alloc_unbound.port; 1021 1022 /* And finally publish the above info in /proc/xen */ 1023 if((xsd_mfn_intf = create_xen_proc_entry("xsd_mfn", 0400))) 1024 xsd_mfn_intf->read_proc = xsd_mfn_read; 1025 if((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400))) 1026 xsd_port_intf->read_proc = xsd_port_read; 1027 } 1028#endif 1029 /* Initialize the interface to xenstore. */ 1030 err = xs_init(); 1031 if (err) { 1032 log(LOG_WARNING, 1033 "XENBUS: Error initializing xenstore comms: %i\n", err); 1034 return err; 1035 } 1036 1037 return 0; | 497 return (ENOENT); |
1038} 1039 | 498} 499 |
1040 1041static int 1042xenbus_probe_sysinit2(void *unused) 1043{ 1044 if (!dom0) { 1045 xenstored_ready = 1; | 500SYSCTL_DECL(_dev); 501SYSCTL_NODE(_dev, OID_AUTO, xen, CTLFLAG_RD, NULL, "Xen"); |
1046#if 0 | 502#if 0 |
1047 xenbus_dev = BUS_ADD_CHILD(parent, 0, "xenbus", 0); 1048 if (xenbus_dev == NULL) 1049 panic("xenbus: could not attach"); 1050 xenbus_backend_dev = BUS_ADD_CHILD(parent, 0, "xb_be", 0); 1051 if (xenbus_backend_dev == NULL) 1052 panic("xenbus: could not attach"); | 503SYSCTL_INT(_dev_xen, OID_AUTO, xsd_port, CTLFLAG_RD, &xen_store_evtchn, 0, ""); 504SYSCTL_ULONG(_dev_xen, OID_AUTO, xsd_kva, CTLFLAG_RD, (u_long *) &xen_store, 0, ""); |
1053#endif | 505#endif |
1054 BUG_ON((xenstored_ready <= 0)); 1055 | |
1056 | 506 |
1057 1058 /* Enumerate devices in xenstore. */ 1059 xenbus_probe_devices(&xenbus_frontend); 1060 register_xenbus_watch(&fe_watch); 1061 xenbus_backend_probe_and_watch(); 1062 1063 /* Notify others that xenstore is up */ 1064 EVENTHANDLER_INVOKE(xenstore_event); 1065 } 1066 return (0); 1067} 1068 1069 1070SYSINIT(xenbus_probe_sysinit, SI_SUB_PSEUDO, SI_ORDER_FIRST, xenbus_probe_sysinit, NULL); 1071SYSINIT(xenbus_probe_sysinit2, SI_SUB_PSEUDO, SI_ORDER_ANY, 1072 xenbus_probe_sysinit2, NULL); 1073 1074#if 0 | |
1075static device_method_t xenbus_methods[] = { 1076 /* Device interface */ | 507static device_method_t xenbus_methods[] = { 508 /* Device interface */ |
1077#if 0 1078 DEVMETHOD(device_identify, xenbus_identify), | 509 DEVMETHOD(device_identify, xenbus_identify), |
1079 DEVMETHOD(device_probe, xenbus_probe), 1080 DEVMETHOD(device_attach, xenbus_attach), | 510 DEVMETHOD(device_probe, xenbus_probe), 511 DEVMETHOD(device_attach, xenbus_attach), |
1081 | |
1082 DEVMETHOD(device_detach, bus_generic_detach), 1083 DEVMETHOD(device_shutdown, bus_generic_shutdown), | 512 DEVMETHOD(device_detach, bus_generic_detach), 513 DEVMETHOD(device_shutdown, bus_generic_shutdown), |
1084#endif | |
1085 DEVMETHOD(device_suspend, xenbus_suspend), 1086 DEVMETHOD(device_resume, xenbus_resume), 1087 1088 /* Bus interface */ | 514 DEVMETHOD(device_suspend, xenbus_suspend), 515 DEVMETHOD(device_resume, xenbus_resume), 516 517 /* Bus interface */ |
1089 DEVMETHOD(bus_print_child, bus_generic_print_child), 1090 DEVMETHOD(bus_add_child, xenbus_add_child), 1091 DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), 1092 DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), 1093#if 0 1094 DEVMETHOD(bus_set_resource, bus_generic_set_resource), 1095 DEVMETHOD(bus_get_resource, bus_generic_get_resource), 1096#endif 1097 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), 1098 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 1099#if 0 1100 DEVMETHOD(bus_delete_resource, bus_generic_delete_resource), 1101#endif 1102 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1103 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 1104 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 1105 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), | 518 DEVMETHOD(bus_print_child, xenbus_print_child), 519 DEVMETHOD(bus_read_ivar, xenbus_read_ivar), 520 DEVMETHOD(bus_write_ivar, xenbus_write_ivar), |
1106 1107 { 0, 0 } 1108}; 1109 1110static char driver_name[] = "xenbus"; 1111static driver_t xenbus_driver = { 1112 driver_name, 1113 xenbus_methods, | 521 522 { 0, 0 } 523}; 524 525static char driver_name[] = "xenbus"; 526static driver_t xenbus_driver = { 527 driver_name, 528 xenbus_methods, |
1114 sizeof(struct xenbus_device), | 529 sizeof(struct xenbus_softc), |
1115}; 1116devclass_t xenbus_devclass; 1117 | 530}; 531devclass_t xenbus_devclass; 532 |
1118DRIVER_MODULE(xenbus, nexus, xenbus_driver, xenbus_devclass, 0, 0); 1119 | 533#ifdef XENHVM 534DRIVER_MODULE(xenbus, xenpci, xenbus_driver, xenbus_devclass, 0, 0); 535#else 536DRIVER_MODULE(xenbus, nexus, xenbus_driver, xenbus_devclass, 0, 0); |
1120#endif | 537#endif |
1121 1122 1123 1124 1125 1126/* 1127 * Local variables: 1128 * c-file-style: "bsd" 1129 * indent-tabs-mode: t 1130 * c-indent-level: 4 1131 * c-basic-offset: 8 1132 * tab-width: 4 1133 * End: 1134 */ | |