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>
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>
105 free(ivars->
xd_type, M_XENBUS);
115 free(ivars, M_XENBUS);
134 unsigned int vec_size __unused)
140 enum xenbus_state newstate;
144 bus = device_get_parent(child);
146 path = vec[XS_WATCH_PATH];
152 XENBUSB_OTHEREND_CHANGED(bus, child, newstate);
172 unsigned int vec_size __unused)
181 bus = device_get_parent(child);
183 path = vec[XS_WATCH_PATH];
188 XENBUSB_LOCALEND_CHANGED(bus, child, &path[ivars->
xd_node_len]);
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)) {
229xenbusb_delete_child(device_t dev, device_t child)
233 ivars = device_get_ivars(child);
246 device_delete_child(dev, child);
257 if (xs_exists(XST_NIL, xenbus_get_node(child),
"") == 0) {
262 xenbusb_delete_child(dev, child);
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);
310 dev = (device_t)arg1;
313 value = xenbus_get_node(dev);
316 value = xenbus_get_type(dev);
322 return (sysctl_handle_int(oidp, NULL,
323 xenbus_get_otherend_id(dev),
327 value = xenbus_get_otherend_path(dev);
332 return (SYSCTL_OUT_STR(req, value));
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,
358 "XenStore path to device");
361 SYSCTL_CHILDREN(tree),
364 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
369 "XenBus device type");
372 SYSCTL_CHILDREN(tree),
374 "xenbus_connection_state",
375 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
380 "XenBus state of peer connection");
383 SYSCTL_CHILDREN(tree),
386 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
391 "Xen domain ID of peer");
394 SYSCTL_CHILDREN(tree),
396 "xenstore_peer_path",
397 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
402 "XenStore path to peer device");
418 (
"Connecting device count error\n"));
421 && (xbs->
xbs_flags & XBS_ATTACH_CH_ACTIVE) != 0) {
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) {
457 error = device_probe_and_attach(kids[i]);
458 if (error == ENXIO) {
469 xenbusb_delete_child(dev, kids[i]);
476 xbs = device_get_softc(dev);
486 xenbus_set_state(kids[i], XenbusStateClosed);
496 xenbusb_delete_child(dev, kids[i]);
512 ivars = device_get_ivars(kids[i]);
534 device_t dev = (device_t)arg;
568 if (len <= XS_WATCH_PATH) {
569 device_printf(dev,
"xenbusb_devices_changed: "
570 "Short Event Data.\n");
574 node = strdup(vec[XS_WATCH_PATH], M_XENBUS);
575 p = strchr(node,
'/');
581 p = strchr(type,
'/');
607 free(node, M_XENBUS);
633 BUS_ADD_CHILD(parent, 0, driver->name, 0);
640 struct sbuf *devpath_sbuf;
645 xbs = device_get_softc(dev);
646 devpath_sbuf = sbuf_new_auto();
647 sbuf_printf(devpath_sbuf,
"%s/%s/%s", xbs->
xbs_node, type,
id);
648 sbuf_finish(devpath_sbuf);
649 devpath = sbuf_data(devpath_sbuf);
651 ivars = malloc(
sizeof(*ivars), M_XENBUS, M_ZERO|M_WAITOK);
654 if (xs_exists(XST_NIL, devpath,
"") != 0) {
656 enum xenbus_state state;
669 if (state != XenbusStateInitialising) {
675 printf(
"xenbusb_add_device: Device %s ignored. "
676 "State %d\n", devpath, state);
681 sx_init(&ivars->
xd_lock,
"xdlock");
683 ivars->
xd_node = strdup(devpath, M_XENBUS);
685 ivars->
xd_type = strdup(type, M_XENBUS);
686 ivars->
xd_state = XenbusStateInitialising;
688 error = XENBUSB_GET_OTHEREND_NODE(dev, ivars);
690 printf(
"xenbus_update_device: %s no otherend id\n",
696 + strlen(
"/state") + 1, M_XENBUS, M_WAITOK);
721 child = device_add_child(dev, NULL, -1);
723 device_set_ivars(child, ivars);
727 sbuf_delete(devpath_sbuf);
739 xbs = device_get_softc(dev);
740 mtx_init(&xbs->
xbs_lock,
"xenbusb softc lock", NULL, MTX_DEF);
802 if (device_get_children(dev, &kids, &count) == 0) {
803 for (i = 0; i < count; i++) {
804 if (device_get_state(kids[i]) == DS_NOTPRESENT)
807 if (xen_suspend_cancelled) {
808 DEVICE_RESUME(kids[i]);
812 ivars = device_get_ivars(kids[i]);
815 xenbus_set_state(kids[i], XenbusStateInitialising);
821 error = XENBUSB_GET_OTHEREND_NODE(dev, ivars);
826 + strlen(
"/state") + 1, M_XENBUS, M_WAITOK);
832 DEVICE_RESUME(kids[i]);
843 while (ivars->
xd_state != XenbusStateClosed
844 && ivars->
xd_state != XenbusStateConnected)
862 retval += bus_print_child_header(dev, child);
863 retval += printf(
" at %s", ivars->
xd_node);
864 retval += bus_print_child_footer(dev, child);
876 *result = (uintptr_t) ivars->
xd_node;
880 *result = (uintptr_t) ivars->
xd_type;
884 *result = (uintptr_t) ivars->
xd_state;
903 enum xenbus_state newstate;
911 newstate = (
enum xenbus_state)value;
918 error = xs_scanf(XST_NIL, ivars->
xd_node,
"state",
919 NULL,
"%d", &currstate);
924 error = xs_printf(XST_NIL, ivars->
xd_node,
"state",
926 }
while (error == EAGAIN);
933 if (newstate != XenbusStateClosing)
935 "writing new state");
941 && (newstate == XenbusStateClosed
942 || newstate == XenbusStateConnected)) {
946 xbs = device_get_softc(dev);
972 XENBUS_OTHEREND_CHANGED(child, state);
979 if (strcmp(path,
"/state") != 0) {
982 ivars = device_get_ivars(child);
987 XENBUS_LOCALEND_CHANGED(child, path);
struct xs_watch xd_local_watch
struct xs_watch xd_otherend_watch
enum xenbus_state xd_state
Container for all state needed to manage a Xenbus Bus attachment.
struct intr_config_hook xbs_attach_ch
struct xs_watch xbs_device_watch
xenbusb_softc_flag xbs_flags
u_int xbs_connecting_children
struct task xbs_probe_children
XenbusState xenbus_read_driver_state(const char *path)
int xenbusb_attach(device_t dev, char *bus_node, u_int id_components)
Perform common XenBus bus attach processing.
static void xenbusb_local_watch_cb(struct xs_watch *watch, const char **vec, unsigned int vec_size __unused)
static void xenbusb_otherend_watch_cb(struct xs_watch *watch, const char **vec, unsigned int vec_size __unused)
int xenbusb_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
Common XenBus child instance variable read access method.
static void xenbusb_release_confighook(struct xenbusb_softc *xbs)
Decrement the number of XenBus child devices in the connecting state by one and release the xbs_attch...
int xenbusb_print_child(device_t dev, device_t child)
Pretty-prints information about a child of a XenBus bus.
static device_t xenbusb_device_exists(device_t dev, const char *node)
static int xenbusb_enumerate_bus(struct xenbusb_softc *xbs)
Enumerate the devices on a XenBus bus and register them with the NewBus device tree.
void xenbusb_localend_changed(device_t bus, device_t child, const char *path)
Common XenBus method implementing responses to local XenStore changes.
static void xenbusb_free_child_ivars(struct xenbus_device_ivars *ivars)
Deallocate XenBus device instance variables.
static void xenbusb_verify_device(device_t dev, device_t child)
static int xenbusb_probe_children(device_t dev)
Verify the existence of attached device instances and perform probe/attach processing for newly arriv...
static int xenbusb_device_sysctl_handler(SYSCTL_HANDLER_ARGS)
int xenbusb_add_device(device_t dev, const char *type, const char *id)
Attempt to add a XenBus device instance to this XenBus bus.
void xenbusb_identify(driver_t *driver __unused, device_t parent)
Identify instances of this device type in the system.
void xenbusb_otherend_changed(device_t bus, device_t child, enum xenbus_state state)
Common XenBus method implementing responses to peer state changes.
static void xenbusb_device_sysctl_init(device_t dev)
static void xenbusb_nop_confighook_cb(void *arg __unused)
Interrupt configuration hook callback associated with xbs_attch_ch.
static void xenbusb_probe_children_cb(void *arg, int pending __unused)
Task callback function to perform XenBus probe operations from a known safe context.
int xenbusb_resume(device_t dev)
Perform common XenBus bus resume handling.
static void xenbusb_devices_changed(struct xs_watch *watch, const char **vec, unsigned int len)
XenStore watch callback for the root node of the XenStore subtree representing a XenBus.
int xenbusb_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
Common XenBus child instance variable write access method.
Datastructures and function declarations for usedby device drivers operating on the XenBus.
void void void xenbus_dev_fatal(device_t dev, int err, const char *fmt,...) __attribute__((format(printf
@ XENBUS_IVAR_OTHEREND_PATH
@ XENBUS_IVAR_OTHEREND_ID
void void void void const char * xenbus_strstate(enum xenbus_state state)