1 /****************************************************************************** 2 * Copyright (C) 2010 Spectra Logic Corporation 3 * 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 12 * of this source file (the "Software"), to deal in the Software without 13 * restriction, including without limitation the rights to use, copy, modify, 14 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 15 * and to permit persons to whom the Software is furnished to do so, subject to 16 * the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be included in 19 * all copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 27 * IN THE SOFTWARE. 28 */ 29 30 /** 31 * \file xenbusb.c 32 * 33 * \brief Shared support functions for managing the NewBus busses that contain 34 * Xen front and back end device instances. 35 * 36 * The NewBus implementation of XenBus attaches a xenbusb_front and xenbusb_back 37 * child bus to the xenstore device. This strategy allows the small differences 38 * in the handling of XenBus operations for front and back devices to be handled 39 * as overrides in xenbusb_front/back.c. Front and back specific device 40 * classes are also provided so device drivers can register for the devices they 41 * can handle without the need to filter within their probe routines. The 42 * net result is a device hierarchy that might look like this: 43 * 44 * xenstore0/ 45 * xenbusb_front0/ 46 * xn0 47 * xbd0 48 * xbd1 49 * xenbusb_back0/ 50 * xbbd0 51 * xnb0 52 * xnb1 53 */ 54 #include <sys/cdefs.h> 55 __FBSDID("$FreeBSD$"); 56 57 #include <sys/param.h> 58 #include <sys/bus.h> 59 #include <sys/kernel.h> 60 #include <sys/lock.h> 61 #include <sys/malloc.h> 62 #include <sys/module.h> 63 #include <sys/sbuf.h> 64 #include <sys/sysctl.h> 65 #include <sys/syslog.h> 66 #include <sys/systm.h> 67 #include <sys/sx.h> 68 #include <sys/taskqueue.h> 69 70 #include <machine/xen/xen-os.h> 71 #include <machine/stdarg.h> 72 73 #include <xen/gnttab.h> 74 #include <xen/xenstore/xenstorevar.h> 75 #include <xen/xenbus/xenbusb.h> 76 #include <xen/xenbus/xenbusvar.h> 77 78 /*------------------------- Private Functions --------------------------------*/ 79 /** 80 * \brief Deallocate XenBus device instance variables. 81 * 82 * \param ivars The instance variable block to free. 83 */ 84 static void 85 xenbusb_free_child_ivars(struct xenbus_device_ivars *ivars) 86 { 87 if (ivars->xd_otherend_watch.node != NULL) { 88 xs_unregister_watch(&ivars->xd_otherend_watch); 89 free(ivars->xd_otherend_watch.node, M_XENBUS); 90 ivars->xd_otherend_watch.node = NULL; 91 } 92 93 if (ivars->xd_node != NULL) { 94 free(ivars->xd_node, M_XENBUS); 95 ivars->xd_node = NULL; 96 } 97 98 if (ivars->xd_type != NULL) { 99 free(ivars->xd_type, M_XENBUS); 100 ivars->xd_type = NULL; 101 } 102 103 if (ivars->xd_otherend_path != NULL) { 104 free(ivars->xd_otherend_path, M_XENBUS); 105 ivars->xd_otherend_path = NULL; 106 } 107 108 free(ivars, M_XENBUS); 109 } 110 111 /** 112 * XenBus watch callback registered against the "state" XenStore 113 * node of the other-end of a split device connection. 114 * 115 * This callback is invoked whenever the state of a device instance's 116 * peer changes. 117 * 118 * \param watch The xs_watch object used to register this callback 119 * function. 120 * \param vec An array of pointers to NUL terminated strings containing 121 * watch event data. The vector should be indexed via the 122 * xs_watch_type enum in xs_wire.h. 123 * \param vec_size The number of elements in vec. 124 * 125 * \return The device_t of the found device if any, or NULL. 126 * 127 * \note device_t is a pointer type, so it can be compared against 128 * NULL for validity. 129 */ 130 static void 131 xenbusb_otherend_changed(struct xs_watch *watch, const char **vec, 132 unsigned int vec_size __unused) 133 { 134 struct xenbus_device_ivars *ivars; 135 device_t dev; 136 enum xenbus_state newstate; 137 138 ivars = (struct xenbus_device_ivars *) watch; 139 dev = ivars->xd_dev; 140 141 if (!ivars->xd_otherend_path 142 || strncmp(ivars->xd_otherend_path, vec[XS_WATCH_PATH], 143 strlen(ivars->xd_otherend_path))) 144 return; 145 146 newstate = xenbus_read_driver_state(ivars->xd_otherend_path); 147 XENBUS_OTHEREND_CHANGED(dev, newstate); 148 } 149 150 /** 151 * Search our internal record of configured devices (not the XenStore) 152 * to determine if the XenBus device indicated by \a node is known to 153 * the system. 154 * 155 * \param dev The XenBus bus instance to search for device children. 156 * \param node The XenStore node path for the device to find. 157 * 158 * \return The device_t of the found device if any, or NULL. 159 * 160 * \note device_t is a pointer type, so it can be compared against 161 * NULL for validity. 162 */ 163 static device_t 164 xenbusb_device_exists(device_t dev, const char *node) 165 { 166 device_t *kids; 167 device_t result; 168 struct xenbus_device_ivars *ivars; 169 int i, count; 170 171 if (device_get_children(dev, &kids, &count)) 172 return (FALSE); 173 174 result = NULL; 175 for (i = 0; i < count; i++) { 176 ivars = device_get_ivars(kids[i]); 177 if (!strcmp(ivars->xd_node, node)) { 178 result = kids[i]; 179 break; 180 } 181 } 182 free(kids, M_TEMP); 183 184 return (result); 185 } 186 187 static void 188 xenbusb_delete_child(device_t dev, device_t child) 189 { 190 struct xenbus_device_ivars *ivars; 191 192 ivars = device_get_ivars(child); 193 194 /* 195 * We no longer care about the otherend of the 196 * connection. Cancel the watch now so that we 197 * don't try to handle an event for a partially 198 * detached child. 199 */ 200 if (ivars->xd_otherend_watch.node != NULL) 201 xs_unregister_watch(&ivars->xd_otherend_watch); 202 203 device_delete_child(dev, child); 204 xenbusb_free_child_ivars(ivars); 205 } 206 207 /** 208 * \param dev The NewBus device representing this XenBus bus. 209 * \param child The NewBus device representing a child of dev%'s XenBus bus. 210 */ 211 static void 212 xenbusb_verify_device(device_t dev, device_t child) 213 { 214 if (xs_exists(XST_NIL, xenbus_get_node(child), "") == 0) { 215 216 /* 217 * Device tree has been removed from Xenbus. 218 * Tear down the device. 219 */ 220 xenbusb_delete_child(dev, child); 221 } 222 } 223 224 /** 225 * \brief Enumerate the devices on a XenBus bus and register them with 226 * the NewBus device tree. 227 * 228 * xenbusb_enumerate_bus() will create entries (in state DS_NOTPRESENT) 229 * for nodes that appear in the XenStore, but will not invoke probe/attach 230 * operations on drivers. Probe/Attach processing must be separately 231 * performed via an invocation of xenbusb_probe_children(). This is usually 232 * done via the xbs_probe_children task. 233 * 234 * \param xbs XenBus Bus device softc of the owner of the bus to enumerate. 235 * 236 * \return On success, 0. Otherwise an errno value indicating the 237 * type of failure. 238 */ 239 static int 240 xenbusb_enumerate_bus(struct xenbusb_softc *xbs) 241 { 242 const char **types; 243 u_int type_idx; 244 u_int type_count; 245 int error; 246 247 error = xs_directory(XST_NIL, xbs->xbs_node, "", &type_count, &types); 248 if (error) 249 return (error); 250 251 for (type_idx = 0; type_idx < type_count; type_idx++) 252 XENBUSB_ENUMERATE_TYPE(xbs->xbs_dev, types[type_idx]); 253 254 free(types, M_XENSTORE); 255 256 return (0); 257 } 258 259 /** 260 * Handler for all generic XenBus device systcl nodes. 261 */ 262 static int 263 xenbusb_device_sysctl_handler(SYSCTL_HANDLER_ARGS) 264 { 265 device_t dev; 266 const char *value; 267 268 dev = (device_t)arg1; 269 switch (arg2) { 270 case XENBUS_IVAR_NODE: 271 value = xenbus_get_node(dev); 272 break; 273 case XENBUS_IVAR_TYPE: 274 value = xenbus_get_type(dev); 275 break; 276 case XENBUS_IVAR_STATE: 277 value = xenbus_strstate(xenbus_get_state(dev)); 278 break; 279 case XENBUS_IVAR_OTHEREND_ID: 280 return (sysctl_handle_int(oidp, NULL, 281 xenbus_get_otherend_id(dev), 282 req)); 283 /* NOTREACHED */ 284 case XENBUS_IVAR_OTHEREND_PATH: 285 value = xenbus_get_otherend_path(dev); 286 break; 287 default: 288 return (EINVAL); 289 } 290 return (SYSCTL_OUT(req, value, strlen(value))); 291 } 292 293 /** 294 * Create read-only systcl nodes for xenbusb device ivar data. 295 * 296 * \param dev The XenBus device instance to register with sysctl. 297 */ 298 static void 299 xenbusb_device_sysctl_init(device_t dev) 300 { 301 struct sysctl_ctx_list *ctx; 302 struct sysctl_oid *tree; 303 304 ctx = device_get_sysctl_ctx(dev); 305 tree = device_get_sysctl_tree(dev); 306 307 SYSCTL_ADD_PROC(ctx, 308 SYSCTL_CHILDREN(tree), 309 OID_AUTO, 310 "xenstore_path", 311 CTLTYPE_STRING | CTLFLAG_RD, 312 dev, 313 XENBUS_IVAR_NODE, 314 xenbusb_device_sysctl_handler, 315 "A", 316 "XenStore path to device"); 317 318 SYSCTL_ADD_PROC(ctx, 319 SYSCTL_CHILDREN(tree), 320 OID_AUTO, 321 "xenbus_dev_type", 322 CTLTYPE_STRING | CTLFLAG_RD, 323 dev, 324 XENBUS_IVAR_TYPE, 325 xenbusb_device_sysctl_handler, 326 "A", 327 "XenBus device type"); 328 329 SYSCTL_ADD_PROC(ctx, 330 SYSCTL_CHILDREN(tree), 331 OID_AUTO, 332 "xenbus_connection_state", 333 CTLTYPE_STRING | CTLFLAG_RD, 334 dev, 335 XENBUS_IVAR_STATE, 336 xenbusb_device_sysctl_handler, 337 "A", 338 "XenBus state of peer connection"); 339 340 SYSCTL_ADD_PROC(ctx, 341 SYSCTL_CHILDREN(tree), 342 OID_AUTO, 343 "xenbus_peer_domid", 344 CTLTYPE_INT | CTLFLAG_RD, 345 dev, 346 XENBUS_IVAR_OTHEREND_ID, 347 xenbusb_device_sysctl_handler, 348 "I", 349 "Xen domain ID of peer"); 350 351 SYSCTL_ADD_PROC(ctx, 352 SYSCTL_CHILDREN(tree), 353 OID_AUTO, 354 "xenstore_peer_path", 355 CTLTYPE_STRING | CTLFLAG_RD, 356 dev, 357 XENBUS_IVAR_OTHEREND_PATH, 358 xenbusb_device_sysctl_handler, 359 "A", 360 "XenStore path to peer device"); 361 } 362 363 /** 364 * \brief Verify the existance of attached device instances and perform 365 * probe/attach processing for newly arrived devices. 366 * 367 * \param dev The NewBus device representing this XenBus bus. 368 * 369 * \return On success, 0. Otherwise an errno value indicating the 370 * type of failure. 371 */ 372 static int 373 xenbusb_probe_children(device_t dev) 374 { 375 device_t *kids; 376 struct xenbus_device_ivars *ivars; 377 int i, count; 378 379 if (device_get_children(dev, &kids, &count) == 0) { 380 for (i = 0; i < count; i++) { 381 if (device_get_state(kids[i]) != DS_NOTPRESENT) { 382 /* 383 * We already know about this one. 384 * Make sure it's still here. 385 */ 386 xenbusb_verify_device(dev, kids[i]); 387 continue; 388 } 389 390 if (device_probe_and_attach(kids[i])) { 391 /* 392 * Transition device to the closed state 393 * so the world knows that attachment will 394 * not occur. 395 */ 396 xenbus_set_state(kids[i], XenbusStateClosed); 397 398 /* 399 * Remove our record of this device. 400 * So long as it remains in the closed 401 * state in the XenStore, we will not find 402 * it again. The state will only change 403 * if the control domain actively reconfigures 404 * this device. 405 */ 406 xenbusb_delete_child(dev, kids[i]); 407 408 continue; 409 } 410 /* 411 * Augment default newbus provided dynamic sysctl 412 * variables with the standard ivar contents of 413 * XenBus devices. 414 */ 415 xenbusb_device_sysctl_init(kids[i]); 416 417 /* 418 * Now that we have a driver managing this device 419 * that can receive otherend state change events, 420 * hook up a watch for them. 421 */ 422 ivars = device_get_ivars(kids[i]); 423 xs_register_watch(&ivars->xd_otherend_watch); 424 } 425 free(kids, M_TEMP); 426 } 427 428 return (0); 429 } 430 431 /** 432 * \brief Task callback function to perform XenBus probe operations 433 * from a known safe context. 434 * 435 * \param arg The NewBus device_t representing the bus instance to 436 * on which to perform probe processing. 437 * \param pending The number of times this task was queued before it could 438 * be run. 439 */ 440 static void 441 xenbusb_probe_children_cb(void *arg, int pending __unused) 442 { 443 device_t dev = (device_t)arg; 444 445 /* 446 * Hold Giant until the Giant free newbus changes are committed. 447 */ 448 mtx_lock(&Giant); 449 xenbusb_probe_children(dev); 450 mtx_unlock(&Giant); 451 } 452 453 /** 454 * \brief XenStore watch callback for the root node of the XenStore 455 * subtree representing a XenBus. 456 * 457 * This callback performs, or delegates to the xbs_probe_children task, 458 * all processing necessary to handle dynmaic device arrival and departure 459 * events from a XenBus. 460 * 461 * \param watch The XenStore watch object associated with this callback. 462 * \param vec The XenStore watch event data. 463 * \param len The number of fields in the event data stream. 464 */ 465 static void 466 xenbusb_devices_changed(struct xs_watch *watch, const char **vec, 467 unsigned int len) 468 { 469 struct xenbusb_softc *xbs; 470 device_t dev; 471 char *node; 472 char *bus; 473 char *type; 474 char *id; 475 char *p; 476 u_int component; 477 478 xbs = (struct xenbusb_softc *)watch; 479 dev = xbs->xbs_dev; 480 481 if (len <= XS_WATCH_PATH) { 482 device_printf(dev, "xenbusb_devices_changed: " 483 "Short Event Data.\n"); 484 return; 485 } 486 487 node = strdup(vec[XS_WATCH_PATH], M_XENBUS); 488 p = strchr(node, '/'); 489 if (p == NULL) 490 goto out; 491 bus = node; 492 *p = 0; 493 type = p + 1; 494 495 p = strchr(type, '/'); 496 if (p == NULL) 497 goto out; 498 *p++ = 0; 499 500 /* 501 * Extract the device ID. A device ID has one or more path 502 * components separated by the '/' character. 503 * 504 * e.g. "<frontend vm id>/<frontend dev id>" for backend devices. 505 */ 506 id = p; 507 for (component = 0; component < xbs->xbs_id_components; component++) { 508 p = strchr(p, '/'); 509 if (p == NULL) 510 break; 511 p++; 512 } 513 if (p != NULL) 514 *p = 0; 515 516 if (*id != 0 && component >= xbs->xbs_id_components - 1) { 517 xenbusb_add_device(xbs->xbs_dev, type, id); 518 taskqueue_enqueue(taskqueue_thread, &xbs->xbs_probe_children); 519 } 520 out: 521 free(node, M_XENBUS); 522 } 523 524 /** 525 * \brief Interrupt configuration hook callback associated with xbs_attch_ch. 526 * 527 * Since interrupts are always functional at the time of XenBus configuration, 528 * there is nothing to be done when the callback occurs. This hook is only 529 * registered to hold up boot processing while XenBus devices come online. 530 * 531 * \param arg Unused configuration hook callback argument. 532 */ 533 static void 534 xenbusb_nop_confighook_cb(void *arg __unused) 535 { 536 } 537 538 /** 539 * \brief Decrement the number of XenBus child devices in the 540 * connecting state by one and release the xbs_attch_ch 541 * interrupt configuration hook if the connecting count 542 * drops to zero. 543 * 544 * \param xbs XenBus Bus device softc of the owner of the bus to enumerate. 545 */ 546 static void 547 xenbusb_release_confighook(struct xenbusb_softc *xbs) 548 { 549 mtx_lock(&xbs->xbs_lock); 550 KASSERT(xbs->xbs_connecting_children > 0, 551 ("Connecting device count error\n")); 552 xbs->xbs_connecting_children--; 553 if (xbs->xbs_connecting_children == 0 554 && (xbs->xbs_flags & XBS_ATTACH_CH_ACTIVE) != 0) { 555 xbs->xbs_flags &= ~XBS_ATTACH_CH_ACTIVE; 556 mtx_unlock(&xbs->xbs_lock); 557 config_intrhook_disestablish(&xbs->xbs_attach_ch); 558 } else { 559 mtx_unlock(&xbs->xbs_lock); 560 } 561 } 562 563 /*--------------------------- Public Functions -------------------------------*/ 564 /*--------- API comments for these methods can be found in xenbusb.h ---------*/ 565 void 566 xenbusb_identify(driver_t *driver __unused, device_t parent) 567 { 568 /* 569 * A single instance of each bus type for which we have a driver 570 * is always present in a system operating under Xen. 571 */ 572 BUS_ADD_CHILD(parent, 0, driver->name, 0); 573 } 574 575 int 576 xenbusb_add_device(device_t dev, const char *type, const char *id) 577 { 578 struct xenbusb_softc *xbs; 579 struct sbuf *devpath_sbuf; 580 char *devpath; 581 struct xenbus_device_ivars *ivars; 582 int error; 583 584 xbs = device_get_softc(dev); 585 devpath_sbuf = sbuf_new_auto(); 586 sbuf_printf(devpath_sbuf, "%s/%s/%s", xbs->xbs_node, type, id); 587 sbuf_finish(devpath_sbuf); 588 devpath = sbuf_data(devpath_sbuf); 589 590 ivars = malloc(sizeof(*ivars), M_XENBUS, M_ZERO|M_WAITOK); 591 error = ENXIO; 592 593 if (xs_exists(XST_NIL, devpath, "") != 0) { 594 device_t child; 595 enum xenbus_state state; 596 char *statepath; 597 598 child = xenbusb_device_exists(dev, devpath); 599 if (child != NULL) { 600 /* 601 * We are already tracking this node 602 */ 603 error = 0; 604 goto out; 605 } 606 607 state = xenbus_read_driver_state(devpath); 608 if (state != XenbusStateInitialising) { 609 /* 610 * Device is not new, so ignore it. This can 611 * happen if a device is going away after 612 * switching to Closed. 613 */ 614 printf("xenbusb_add_device: Device %s ignored. " 615 "State %d\n", devpath, state); 616 error = 0; 617 goto out; 618 } 619 620 sx_init(&ivars->xd_lock, "xdlock"); 621 ivars->xd_flags = XDF_CONNECTING; 622 ivars->xd_node = strdup(devpath, M_XENBUS); 623 ivars->xd_type = strdup(type, M_XENBUS); 624 ivars->xd_state = XenbusStateInitialising; 625 626 error = XENBUSB_GET_OTHEREND_NODE(dev, ivars); 627 if (error) { 628 printf("xenbus_update_device: %s no otherend id\n", 629 devpath); 630 goto out; 631 } 632 633 statepath = malloc(strlen(ivars->xd_otherend_path) 634 + strlen("/state") + 1, M_XENBUS, M_WAITOK); 635 sprintf(statepath, "%s/state", ivars->xd_otherend_path); 636 637 ivars->xd_otherend_watch.node = statepath; 638 ivars->xd_otherend_watch.callback = xenbusb_otherend_changed; 639 640 mtx_lock(&xbs->xbs_lock); 641 xbs->xbs_connecting_children++; 642 mtx_unlock(&xbs->xbs_lock); 643 644 child = device_add_child(dev, NULL, -1); 645 ivars->xd_dev = child; 646 device_set_ivars(child, ivars); 647 } 648 649 out: 650 sbuf_delete(devpath_sbuf); 651 if (error != 0) 652 xenbusb_free_child_ivars(ivars); 653 654 return (error); 655 } 656 657 int 658 xenbusb_attach(device_t dev, char *bus_node, u_int id_components) 659 { 660 struct xenbusb_softc *xbs; 661 662 xbs = device_get_softc(dev); 663 mtx_init(&xbs->xbs_lock, "xenbusb softc lock", NULL, MTX_DEF); 664 xbs->xbs_node = bus_node; 665 xbs->xbs_id_components = id_components; 666 xbs->xbs_dev = dev; 667 668 /* 669 * Since XenBus busses are attached to the XenStore, and 670 * the XenStore does not probe children until after interrupt 671 * services are available, this config hook is used solely 672 * to ensure that the remainder of the boot process (e.g. 673 * mount root) is deferred until child devices are adequately 674 * probed. We unblock the boot process as soon as the 675 * connecting child count in our softc goes to 0. 676 */ 677 xbs->xbs_attach_ch.ich_func = xenbusb_nop_confighook_cb; 678 xbs->xbs_attach_ch.ich_arg = dev; 679 config_intrhook_establish(&xbs->xbs_attach_ch); 680 xbs->xbs_flags |= XBS_ATTACH_CH_ACTIVE; 681 xbs->xbs_connecting_children = 1; 682 683 /* 684 * The subtree for this bus type may not yet exist 685 * causing initial enumeration to fail. We still 686 * want to return success from our attach though 687 * so that we are ready to handle devices for this 688 * bus when they are dynamically attached to us 689 * by a Xen management action. 690 */ 691 (void)xenbusb_enumerate_bus(xbs); 692 xenbusb_probe_children(dev); 693 694 xbs->xbs_device_watch.node = bus_node; 695 xbs->xbs_device_watch.callback = xenbusb_devices_changed; 696 697 TASK_INIT(&xbs->xbs_probe_children, 0, xenbusb_probe_children_cb, dev); 698 699 xs_register_watch(&xbs->xbs_device_watch); 700 701 xenbusb_release_confighook(xbs); 702 703 return (0); 704 } 705 706 int 707 xenbusb_resume(device_t dev) 708 { 709 device_t *kids; 710 struct xenbus_device_ivars *ivars; 711 int i, count, error; 712 char *statepath; 713 714 /* 715 * We must re-examine each device and find the new path for 716 * its backend. 717 */ 718 if (device_get_children(dev, &kids, &count) == 0) { 719 for (i = 0; i < count; i++) { 720 if (device_get_state(kids[i]) == DS_NOTPRESENT) 721 continue; 722 723 ivars = device_get_ivars(kids[i]); 724 725 xs_unregister_watch(&ivars->xd_otherend_watch); 726 ivars->xd_state = XenbusStateInitialising; 727 728 /* 729 * Find the new backend details and 730 * re-register our watch. 731 */ 732 error = XENBUSB_GET_OTHEREND_NODE(dev, ivars); 733 if (error) 734 return (error); 735 736 DEVICE_RESUME(kids[i]); 737 738 statepath = malloc(strlen(ivars->xd_otherend_path) 739 + strlen("/state") + 1, M_XENBUS, M_WAITOK); 740 sprintf(statepath, "%s/state", ivars->xd_otherend_path); 741 742 free(ivars->xd_otherend_watch.node, M_XENBUS); 743 ivars->xd_otherend_watch.node = statepath; 744 xs_register_watch(&ivars->xd_otherend_watch); 745 746 #if 0 747 /* 748 * Can't do this yet since we are running in 749 * the xenwatch thread and if we sleep here, 750 * we will stop delivering watch notifications 751 * and the device will never come back online. 752 */ 753 sx_xlock(&ivars->xd_lock); 754 while (ivars->xd_state != XenbusStateClosed 755 && ivars->xd_state != XenbusStateConnected) 756 sx_sleep(&ivars->xd_state, &ivars->xd_lock, 757 0, "xdresume", 0); 758 sx_xunlock(&ivars->xd_lock); 759 #endif 760 } 761 free(kids, M_TEMP); 762 } 763 764 return (0); 765 } 766 767 int 768 xenbusb_print_child(device_t dev, device_t child) 769 { 770 struct xenbus_device_ivars *ivars = device_get_ivars(child); 771 int retval = 0; 772 773 retval += bus_print_child_header(dev, child); 774 retval += printf(" at %s", ivars->xd_node); 775 retval += bus_print_child_footer(dev, child); 776 777 return (retval); 778 } 779 780 int 781 xenbusb_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) 782 { 783 struct xenbus_device_ivars *ivars = device_get_ivars(child); 784 785 switch (index) { 786 case XENBUS_IVAR_NODE: 787 *result = (uintptr_t) ivars->xd_node; 788 return (0); 789 790 case XENBUS_IVAR_TYPE: 791 *result = (uintptr_t) ivars->xd_type; 792 return (0); 793 794 case XENBUS_IVAR_STATE: 795 *result = (uintptr_t) ivars->xd_state; 796 return (0); 797 798 case XENBUS_IVAR_OTHEREND_ID: 799 *result = (uintptr_t) ivars->xd_otherend_id; 800 return (0); 801 802 case XENBUS_IVAR_OTHEREND_PATH: 803 *result = (uintptr_t) ivars->xd_otherend_path; 804 return (0); 805 } 806 807 return (ENOENT); 808 } 809 810 int 811 xenbusb_write_ivar(device_t dev, device_t child, int index, uintptr_t value) 812 { 813 struct xenbus_device_ivars *ivars = device_get_ivars(child); 814 enum xenbus_state newstate; 815 int currstate; 816 817 switch (index) { 818 case XENBUS_IVAR_STATE: 819 { 820 int error; 821 822 newstate = (enum xenbus_state) value; 823 sx_xlock(&ivars->xd_lock); 824 if (ivars->xd_state == newstate) { 825 error = 0; 826 goto out; 827 } 828 829 error = xs_scanf(XST_NIL, ivars->xd_node, "state", 830 NULL, "%d", &currstate); 831 if (error) 832 goto out; 833 834 do { 835 error = xs_printf(XST_NIL, ivars->xd_node, "state", 836 "%d", newstate); 837 } while (error == EAGAIN); 838 if (error) { 839 /* 840 * Avoid looping through xenbus_dev_fatal() 841 * which calls xenbus_write_ivar to set the 842 * state to closing. 843 */ 844 if (newstate != XenbusStateClosing) 845 xenbus_dev_fatal(dev, error, 846 "writing new state"); 847 goto out; 848 } 849 ivars->xd_state = newstate; 850 851 if ((ivars->xd_flags & XDF_CONNECTING) != 0 852 && (newstate == XenbusStateClosed 853 || newstate == XenbusStateConnected)) { 854 struct xenbusb_softc *xbs; 855 856 ivars->xd_flags &= ~XDF_CONNECTING; 857 xbs = device_get_softc(dev); 858 xenbusb_release_confighook(xbs); 859 } 860 861 wakeup(&ivars->xd_state); 862 out: 863 sx_xunlock(&ivars->xd_lock); 864 return (error); 865 } 866 867 case XENBUS_IVAR_NODE: 868 case XENBUS_IVAR_TYPE: 869 case XENBUS_IVAR_OTHEREND_ID: 870 case XENBUS_IVAR_OTHEREND_PATH: 871 /* 872 * These variables are read-only. 873 */ 874 return (EINVAL); 875 } 876 877 return (ENOENT); 878 } 879