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
8 * This file may be distributed separately from the Linux kernel, or
9 * incorporated into other software packages, subject to the following license:
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:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
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
33 * \brief Shared support functions for managing the NewBus buses that contain
34 * Xen front and back end device instances.
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:
54 #include <sys/cdefs.h>
55 __FBSDID("$FreeBSD$");
57 #include <sys/param.h>
59 #include <sys/kernel.h>
61 #include <sys/malloc.h>
62 #include <sys/module.h>
64 #include <sys/sysctl.h>
65 #include <sys/syslog.h>
66 #include <sys/systm.h>
68 #include <sys/taskqueue.h>
70 #include <machine/stdarg.h>
72 #include <xen/xen-os.h>
73 #include <xen/gnttab.h>
74 #include <xen/xenstore/xenstorevar.h>
75 #include <xen/xenbus/xenbusb.h>
76 #include <xen/xenbus/xenbusvar.h>
78 /*------------------------- Private Functions --------------------------------*/
80 * \brief Deallocate XenBus device instance variables.
82 * \param ivars The instance variable block to free.
85 xenbusb_free_child_ivars(struct xenbus_device_ivars *ivars)
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;
93 if (ivars->xd_local_watch.node != NULL) {
94 xs_unregister_watch(&ivars->xd_local_watch);
95 ivars->xd_local_watch.node = NULL;
98 if (ivars->xd_node != NULL) {
99 free(ivars->xd_node, M_XENBUS);
100 ivars->xd_node = NULL;
102 ivars->xd_node_len = 0;
104 if (ivars->xd_type != NULL) {
105 free(ivars->xd_type, M_XENBUS);
106 ivars->xd_type = NULL;
109 if (ivars->xd_otherend_path != NULL) {
110 free(ivars->xd_otherend_path, M_XENBUS);
111 ivars->xd_otherend_path = NULL;
113 ivars->xd_otherend_path_len = 0;
115 free(ivars, M_XENBUS);
119 * XenBus watch callback registered against the "state" XenStore
120 * node of the other-end of a split device connection.
122 * This callback is invoked whenever the state of a device instance's
125 * \param watch The xs_watch object used to register this callback
127 * \param vec An array of pointers to NUL terminated strings containing
128 * watch event data. The vector should be indexed via the
129 * xs_watch_type enum in xs_wire.h.
130 * \param vec_size The number of elements in vec.
133 xenbusb_otherend_watch_cb(struct xs_watch *watch, const char **vec,
134 unsigned int vec_size __unused)
136 struct xenbus_device_ivars *ivars;
140 enum xenbus_state newstate;
142 ivars = (struct xenbus_device_ivars *)watch->callback_data;
143 child = ivars->xd_dev;
144 bus = device_get_parent(child);
146 path = vec[XS_WATCH_PATH];
147 if (ivars->xd_otherend_path == NULL
148 || strncmp(ivars->xd_otherend_path, path, ivars->xd_otherend_path_len))
151 newstate = xenbus_read_driver_state(ivars->xd_otherend_path);
152 XENBUSB_OTHEREND_CHANGED(bus, child, newstate);
156 * XenBus watch callback registered against the XenStore sub-tree
157 * represnting the local half of a split device connection.
159 * This callback is invoked whenever any XenStore data in the subtree
160 * is modified, either by us or another privledged domain.
162 * \param watch The xs_watch object used to register this callback
164 * \param vec An array of pointers to NUL terminated strings containing
165 * watch event data. The vector should be indexed via the
166 * xs_watch_type enum in xs_wire.h.
167 * \param vec_size The number of elements in vec.
171 xenbusb_local_watch_cb(struct xs_watch *watch, const char **vec,
172 unsigned int vec_size __unused)
174 struct xenbus_device_ivars *ivars;
179 ivars = (struct xenbus_device_ivars *)watch->callback_data;
180 child = ivars->xd_dev;
181 bus = device_get_parent(child);
183 path = vec[XS_WATCH_PATH];
184 if (ivars->xd_node == NULL
185 || strncmp(ivars->xd_node, path, ivars->xd_node_len))
188 XENBUSB_LOCALEND_CHANGED(bus, child, &path[ivars->xd_node_len]);
192 * Search our internal record of configured devices (not the XenStore)
193 * to determine if the XenBus device indicated by \a node is known to
196 * \param dev The XenBus bus instance to search for device children.
197 * \param node The XenStore node path for the device to find.
199 * \return The device_t of the found device if any, or NULL.
201 * \note device_t is a pointer type, so it can be compared against
205 xenbusb_device_exists(device_t dev, const char *node)
209 struct xenbus_device_ivars *ivars;
212 if (device_get_children(dev, &kids, &count))
216 for (i = 0; i < count; i++) {
217 ivars = device_get_ivars(kids[i]);
218 if (!strcmp(ivars->xd_node, node)) {
229 xenbusb_delete_child(device_t dev, device_t child)
231 struct xenbus_device_ivars *ivars;
233 ivars = device_get_ivars(child);
236 * We no longer care about the otherend of the
237 * connection. Cancel the watches now so that we
238 * don't try to handle an event for a partially
241 if (ivars->xd_otherend_watch.node != NULL)
242 xs_unregister_watch(&ivars->xd_otherend_watch);
243 if (ivars->xd_local_watch.node != NULL)
244 xs_unregister_watch(&ivars->xd_local_watch);
246 device_delete_child(dev, child);
247 xenbusb_free_child_ivars(ivars);
251 * \param dev The NewBus device representing this XenBus bus.
252 * \param child The NewBus device representing a child of dev%'s XenBus bus.
255 xenbusb_verify_device(device_t dev, device_t child)
257 if (xs_exists(XST_NIL, xenbus_get_node(child), "") == 0) {
259 * Device tree has been removed from Xenbus.
260 * Tear down the device.
262 xenbusb_delete_child(dev, child);
267 * \brief Enumerate the devices on a XenBus bus and register them with
268 * the NewBus device tree.
270 * xenbusb_enumerate_bus() will create entries (in state DS_NOTPRESENT)
271 * for nodes that appear in the XenStore, but will not invoke probe/attach
272 * operations on drivers. Probe/Attach processing must be separately
273 * performed via an invocation of xenbusb_probe_children(). This is usually
274 * done via the xbs_probe_children task.
276 * \param xbs XenBus Bus device softc of the owner of the bus to enumerate.
278 * \return On success, 0. Otherwise an errno value indicating the
282 xenbusb_enumerate_bus(struct xenbusb_softc *xbs)
289 error = xs_directory(XST_NIL, xbs->xbs_node, "", &type_count, &types);
293 for (type_idx = 0; type_idx < type_count; type_idx++)
294 XENBUSB_ENUMERATE_TYPE(xbs->xbs_dev, types[type_idx]);
296 free(types, M_XENSTORE);
302 * Handler for all generic XenBus device systcl nodes.
305 xenbusb_device_sysctl_handler(SYSCTL_HANDLER_ARGS)
310 dev = (device_t)arg1;
312 case XENBUS_IVAR_NODE:
313 value = xenbus_get_node(dev);
315 case XENBUS_IVAR_TYPE:
316 value = xenbus_get_type(dev);
318 case XENBUS_IVAR_STATE:
319 value = xenbus_strstate(xenbus_get_state(dev));
321 case XENBUS_IVAR_OTHEREND_ID:
322 return (sysctl_handle_int(oidp, NULL,
323 xenbus_get_otherend_id(dev),
326 case XENBUS_IVAR_OTHEREND_PATH:
327 value = xenbus_get_otherend_path(dev);
332 return (SYSCTL_OUT_STR(req, value));
336 * Create read-only systcl nodes for xenbusb device ivar data.
338 * \param dev The XenBus device instance to register with sysctl.
341 xenbusb_device_sysctl_init(device_t dev)
343 struct sysctl_ctx_list *ctx;
344 struct sysctl_oid *tree;
346 ctx = device_get_sysctl_ctx(dev);
347 tree = device_get_sysctl_tree(dev);
350 SYSCTL_CHILDREN(tree),
353 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
356 xenbusb_device_sysctl_handler,
358 "XenStore path to device");
361 SYSCTL_CHILDREN(tree),
364 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
367 xenbusb_device_sysctl_handler,
369 "XenBus device type");
372 SYSCTL_CHILDREN(tree),
374 "xenbus_connection_state",
375 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
378 xenbusb_device_sysctl_handler,
380 "XenBus state of peer connection");
383 SYSCTL_CHILDREN(tree),
386 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
388 XENBUS_IVAR_OTHEREND_ID,
389 xenbusb_device_sysctl_handler,
391 "Xen domain ID of peer");
394 SYSCTL_CHILDREN(tree),
396 "xenstore_peer_path",
397 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
399 XENBUS_IVAR_OTHEREND_PATH,
400 xenbusb_device_sysctl_handler,
402 "XenStore path to peer device");
406 * \brief Decrement the number of XenBus child devices in the
407 * connecting state by one and release the xbs_attch_ch
408 * interrupt configuration hook if the connecting count
411 * \param xbs XenBus Bus device softc of the owner of the bus to enumerate.
414 xenbusb_release_confighook(struct xenbusb_softc *xbs)
416 mtx_lock(&xbs->xbs_lock);
417 KASSERT(xbs->xbs_connecting_children > 0,
418 ("Connecting device count error\n"));
419 xbs->xbs_connecting_children--;
420 if (xbs->xbs_connecting_children == 0
421 && (xbs->xbs_flags & XBS_ATTACH_CH_ACTIVE) != 0) {
422 xbs->xbs_flags &= ~XBS_ATTACH_CH_ACTIVE;
423 mtx_unlock(&xbs->xbs_lock);
424 config_intrhook_disestablish(&xbs->xbs_attach_ch);
426 mtx_unlock(&xbs->xbs_lock);
431 * \brief Verify the existance of attached device instances and perform
432 * probe/attach processing for newly arrived devices.
434 * \param dev The NewBus device representing this XenBus bus.
436 * \return On success, 0. Otherwise an errno value indicating the
440 xenbusb_probe_children(device_t dev)
443 struct xenbus_device_ivars *ivars;
446 if (device_get_children(dev, &kids, &count) == 0) {
447 for (i = 0; i < count; i++) {
448 if (device_get_state(kids[i]) != DS_NOTPRESENT) {
450 * We already know about this one.
451 * Make sure it's still here.
453 xenbusb_verify_device(dev, kids[i]);
457 error = device_probe_and_attach(kids[i]);
458 if (error == ENXIO) {
459 struct xenbusb_softc *xbs;
462 * We don't have a PV driver for this device.
463 * However, an emulated device we do support
464 * may share this backend. Hide the node from
465 * XenBus until the next rescan, but leave it's
466 * state unchanged so we don't inadvertently
467 * prevent attachment of any emulated device.
469 xenbusb_delete_child(dev, kids[i]);
472 * Since the XenStore state of this device
473 * still indicates a pending attach, manually
474 * release it's hold on the boot process.
476 xbs = device_get_softc(dev);
477 xenbusb_release_confighook(xbs);
482 * Transition device to the closed state
483 * so the world knows that attachment will
486 xenbus_set_state(kids[i], XenbusStateClosed);
489 * Remove our record of this device.
490 * So long as it remains in the closed
491 * state in the XenStore, we will not find
492 * it again. The state will only change
493 * if the control domain actively reconfigures
496 xenbusb_delete_child(dev, kids[i]);
501 * Augment default newbus provided dynamic sysctl
502 * variables with the standard ivar contents of
505 xenbusb_device_sysctl_init(kids[i]);
508 * Now that we have a driver managing this device
509 * that can receive otherend state change events,
510 * hook up a watch for them.
512 ivars = device_get_ivars(kids[i]);
513 xs_register_watch(&ivars->xd_otherend_watch);
514 xs_register_watch(&ivars->xd_local_watch);
523 * \brief Task callback function to perform XenBus probe operations
524 * from a known safe context.
526 * \param arg The NewBus device_t representing the bus instance to
527 * on which to perform probe processing.
528 * \param pending The number of times this task was queued before it could
532 xenbusb_probe_children_cb(void *arg, int pending __unused)
534 device_t dev = (device_t)arg;
537 * Hold Giant until the Giant free newbus changes are committed.
540 xenbusb_probe_children(dev);
545 * \brief XenStore watch callback for the root node of the XenStore
546 * subtree representing a XenBus.
548 * This callback performs, or delegates to the xbs_probe_children task,
549 * all processing necessary to handle dynmaic device arrival and departure
550 * events from a XenBus.
552 * \param watch The XenStore watch object associated with this callback.
553 * \param vec The XenStore watch event data.
554 * \param len The number of fields in the event data stream.
557 xenbusb_devices_changed(struct xs_watch *watch, const char **vec,
560 struct xenbusb_softc *xbs;
568 xbs = (struct xenbusb_softc *)watch->callback_data;
571 if (len <= XS_WATCH_PATH) {
572 device_printf(dev, "xenbusb_devices_changed: "
573 "Short Event Data.\n");
577 node = strdup(vec[XS_WATCH_PATH], M_XENBUS);
578 p = strchr(node, '/');
584 p = strchr(type, '/');
590 * Extract the device ID. A device ID has one or more path
591 * components separated by the '/' character.
593 * e.g. "<frontend vm id>/<frontend dev id>" for backend devices.
596 for (component = 0; component < xbs->xbs_id_components; component++) {
605 if (*id != 0 && component >= xbs->xbs_id_components - 1) {
606 xenbusb_add_device(xbs->xbs_dev, type, id);
607 taskqueue_enqueue(taskqueue_thread, &xbs->xbs_probe_children);
610 free(node, M_XENBUS);
614 * \brief Interrupt configuration hook callback associated with xbs_attch_ch.
616 * Since interrupts are always functional at the time of XenBus configuration,
617 * there is nothing to be done when the callback occurs. This hook is only
618 * registered to hold up boot processing while XenBus devices come online.
620 * \param arg Unused configuration hook callback argument.
623 xenbusb_nop_confighook_cb(void *arg __unused)
627 /*--------------------------- Public Functions -------------------------------*/
628 /*--------- API comments for these methods can be found in xenbusb.h ---------*/
630 xenbusb_identify(driver_t *driver __unused, device_t parent)
633 * A single instance of each bus type for which we have a driver
634 * is always present in a system operating under Xen.
636 BUS_ADD_CHILD(parent, 0, driver->name, 0);
640 xenbusb_add_device(device_t dev, const char *type, const char *id)
642 struct xenbusb_softc *xbs;
643 struct sbuf *devpath_sbuf;
645 struct xenbus_device_ivars *ivars;
648 xbs = device_get_softc(dev);
649 devpath_sbuf = sbuf_new_auto();
650 sbuf_printf(devpath_sbuf, "%s/%s/%s", xbs->xbs_node, type, id);
651 sbuf_finish(devpath_sbuf);
652 devpath = sbuf_data(devpath_sbuf);
654 ivars = malloc(sizeof(*ivars), M_XENBUS, M_ZERO|M_WAITOK);
657 if (xs_exists(XST_NIL, devpath, "") != 0) {
659 enum xenbus_state state;
662 child = xenbusb_device_exists(dev, devpath);
665 * We are already tracking this node
671 state = xenbus_read_driver_state(devpath);
672 if (state != XenbusStateInitialising) {
674 * Device is not new, so ignore it. This can
675 * happen if a device is going away after
676 * switching to Closed.
678 printf("xenbusb_add_device: Device %s ignored. "
679 "State %d\n", devpath, state);
684 sx_init(&ivars->xd_lock, "xdlock");
685 ivars->xd_flags = XDF_CONNECTING;
686 ivars->xd_node = strdup(devpath, M_XENBUS);
687 ivars->xd_node_len = strlen(devpath);
688 ivars->xd_type = strdup(type, M_XENBUS);
689 ivars->xd_state = XenbusStateInitialising;
691 error = XENBUSB_GET_OTHEREND_NODE(dev, ivars);
693 printf("xenbus_update_device: %s no otherend id\n",
698 statepath = malloc(ivars->xd_otherend_path_len
699 + strlen("/state") + 1, M_XENBUS, M_WAITOK);
700 sprintf(statepath, "%s/state", ivars->xd_otherend_path);
701 ivars->xd_otherend_watch.node = statepath;
702 ivars->xd_otherend_watch.callback = xenbusb_otherend_watch_cb;
703 ivars->xd_otherend_watch.callback_data = (uintptr_t)ivars;
705 * Other end state node watch, limit to one pending event
706 * to prevent frontends from queuing too many events that
707 * could cause resource starvation.
709 ivars->xd_otherend_watch.max_pending = 1;
711 ivars->xd_local_watch.node = ivars->xd_node;
712 ivars->xd_local_watch.callback = xenbusb_local_watch_cb;
713 ivars->xd_local_watch.callback_data = (uintptr_t)ivars;
715 * Watch our local path, only writable by us or a privileged
716 * domain, no need to limit.
718 ivars->xd_local_watch.max_pending = 0;
720 mtx_lock(&xbs->xbs_lock);
721 xbs->xbs_connecting_children++;
722 mtx_unlock(&xbs->xbs_lock);
724 child = device_add_child(dev, NULL, -1);
725 ivars->xd_dev = child;
726 device_set_ivars(child, ivars);
730 sbuf_delete(devpath_sbuf);
732 xenbusb_free_child_ivars(ivars);
738 xenbusb_attach(device_t dev, char *bus_node, u_int id_components)
740 struct xenbusb_softc *xbs;
742 xbs = device_get_softc(dev);
743 mtx_init(&xbs->xbs_lock, "xenbusb softc lock", NULL, MTX_DEF);
744 xbs->xbs_node = bus_node;
745 xbs->xbs_id_components = id_components;
749 * Since XenBus buses are attached to the XenStore, and
750 * the XenStore does not probe children until after interrupt
751 * services are available, this config hook is used solely
752 * to ensure that the remainder of the boot process (e.g.
753 * mount root) is deferred until child devices are adequately
754 * probed. We unblock the boot process as soon as the
755 * connecting child count in our softc goes to 0.
757 xbs->xbs_attach_ch.ich_func = xenbusb_nop_confighook_cb;
758 xbs->xbs_attach_ch.ich_arg = dev;
759 config_intrhook_establish(&xbs->xbs_attach_ch);
760 xbs->xbs_flags |= XBS_ATTACH_CH_ACTIVE;
761 xbs->xbs_connecting_children = 1;
764 * The subtree for this bus type may not yet exist
765 * causing initial enumeration to fail. We still
766 * want to return success from our attach though
767 * so that we are ready to handle devices for this
768 * bus when they are dynamically attached to us
769 * by a Xen management action.
771 (void)xenbusb_enumerate_bus(xbs);
772 xenbusb_probe_children(dev);
774 xbs->xbs_device_watch.node = bus_node;
775 xbs->xbs_device_watch.callback = xenbusb_devices_changed;
776 xbs->xbs_device_watch.callback_data = (uintptr_t)xbs;
778 * Allow for unlimited pending watches, as those are local paths
779 * either controlled by the guest or only writable by privileged
782 xbs->xbs_device_watch.max_pending = 0;
784 TASK_INIT(&xbs->xbs_probe_children, 0, xenbusb_probe_children_cb, dev);
786 xs_register_watch(&xbs->xbs_device_watch);
788 xenbusb_release_confighook(xbs);
794 xenbusb_resume(device_t dev)
797 struct xenbus_device_ivars *ivars;
802 * We must re-examine each device and find the new path for
805 if (device_get_children(dev, &kids, &count) == 0) {
806 for (i = 0; i < count; i++) {
807 if (device_get_state(kids[i]) == DS_NOTPRESENT)
810 if (xen_suspend_cancelled) {
811 DEVICE_RESUME(kids[i]);
815 ivars = device_get_ivars(kids[i]);
817 xs_unregister_watch(&ivars->xd_otherend_watch);
818 xenbus_set_state(kids[i], XenbusStateInitialising);
821 * Find the new backend details and
822 * re-register our watch.
824 error = XENBUSB_GET_OTHEREND_NODE(dev, ivars);
828 statepath = malloc(ivars->xd_otherend_path_len
829 + strlen("/state") + 1, M_XENBUS, M_WAITOK);
830 sprintf(statepath, "%s/state", ivars->xd_otherend_path);
832 free(ivars->xd_otherend_watch.node, M_XENBUS);
833 ivars->xd_otherend_watch.node = statepath;
835 DEVICE_RESUME(kids[i]);
837 xs_register_watch(&ivars->xd_otherend_watch);
840 * Can't do this yet since we are running in
841 * the xenwatch thread and if we sleep here,
842 * we will stop delivering watch notifications
843 * and the device will never come back online.
845 sx_xlock(&ivars->xd_lock);
846 while (ivars->xd_state != XenbusStateClosed
847 && ivars->xd_state != XenbusStateConnected)
848 sx_sleep(&ivars->xd_state, &ivars->xd_lock,
850 sx_xunlock(&ivars->xd_lock);
860 xenbusb_print_child(device_t dev, device_t child)
862 struct xenbus_device_ivars *ivars = device_get_ivars(child);
865 retval += bus_print_child_header(dev, child);
866 retval += printf(" at %s", ivars->xd_node);
867 retval += bus_print_child_footer(dev, child);
873 xenbusb_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
875 struct xenbus_device_ivars *ivars = device_get_ivars(child);
878 case XENBUS_IVAR_NODE:
879 *result = (uintptr_t) ivars->xd_node;
882 case XENBUS_IVAR_TYPE:
883 *result = (uintptr_t) ivars->xd_type;
886 case XENBUS_IVAR_STATE:
887 *result = (uintptr_t) ivars->xd_state;
890 case XENBUS_IVAR_OTHEREND_ID:
891 *result = (uintptr_t) ivars->xd_otherend_id;
894 case XENBUS_IVAR_OTHEREND_PATH:
895 *result = (uintptr_t) ivars->xd_otherend_path;
903 xenbusb_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
905 struct xenbus_device_ivars *ivars = device_get_ivars(child);
906 enum xenbus_state newstate;
910 case XENBUS_IVAR_STATE:
914 newstate = (enum xenbus_state)value;
915 sx_xlock(&ivars->xd_lock);
916 if (ivars->xd_state == newstate) {
921 error = xs_scanf(XST_NIL, ivars->xd_node, "state",
922 NULL, "%d", &currstate);
927 error = xs_printf(XST_NIL, ivars->xd_node, "state",
929 } while (error == EAGAIN);
932 * Avoid looping through xenbus_dev_fatal()
933 * which calls xenbus_write_ivar to set the
936 if (newstate != XenbusStateClosing)
937 xenbus_dev_fatal(dev, error,
938 "writing new state");
941 ivars->xd_state = newstate;
943 if ((ivars->xd_flags & XDF_CONNECTING) != 0
944 && (newstate == XenbusStateClosed
945 || newstate == XenbusStateConnected)) {
946 struct xenbusb_softc *xbs;
948 ivars->xd_flags &= ~XDF_CONNECTING;
949 xbs = device_get_softc(dev);
950 xenbusb_release_confighook(xbs);
953 wakeup(&ivars->xd_state);
955 sx_xunlock(&ivars->xd_lock);
959 case XENBUS_IVAR_NODE:
960 case XENBUS_IVAR_TYPE:
961 case XENBUS_IVAR_OTHEREND_ID:
962 case XENBUS_IVAR_OTHEREND_PATH:
964 * These variables are read-only.
973 xenbusb_otherend_changed(device_t bus, device_t child, enum xenbus_state state)
975 XENBUS_OTHEREND_CHANGED(child, state);
979 xenbusb_localend_changed(device_t bus, device_t child, const char *path)
982 if (strcmp(path, "/state") != 0) {
983 struct xenbus_device_ivars *ivars;
985 ivars = device_get_ivars(child);
986 sx_xlock(&ivars->xd_lock);
987 ivars->xd_state = xenbus_read_driver_state(ivars->xd_node);
988 sx_xunlock(&ivars->xd_lock);
990 XENBUS_LOCALEND_CHANGED(child, path);