Exemple #1
0
int 
xenbus_watch_path(device_t dev, char *path, struct xs_watch *watch, 
    xs_watch_cb_t *callback, uintptr_t callback_data)
{
	int error;

	watch->node = path;
	watch->callback = callback;
	watch->callback_data = callback_data;

	error = xs_register_watch(watch);

	if (error) {
		watch->node = NULL;
		watch->callback = NULL;
		xenbus_dev_fatal(dev, error, "adding watch on %s", path);
	}

	return (error);
}
Exemple #2
0
/**
 * \brief Verify the existance of attached device instances and perform
 *        probe/attach processing for newly arrived devices.
 *
 * \param dev  The NewBus device representing this XenBus bus.
 *
 * \return  On success, 0. Otherwise an errno value indicating the
 *          type of failure.
 */
static int
xenbusb_probe_children(device_t dev)
{
	device_t *kids;
	struct xenbus_device_ivars *ivars;
	int i, count, error;

	if (device_get_children(dev, &kids, &count) == 0) {
		for (i = 0; i < count; i++) {
			if (device_get_state(kids[i]) != DS_NOTPRESENT) {
				/*
				 * We already know about this one.
				 * Make sure it's still here.
				 */
				xenbusb_verify_device(dev, kids[i]);
				continue;
			}

			error = device_probe_and_attach(kids[i]);
			if (error == ENXIO) {
				struct xenbusb_softc *xbs;

				/*
				 * We don't have a PV driver for this device.
				 * However, an emulated device we do support
				 * may share this backend.  Hide the node from
				 * XenBus until the next rescan, but leave it's
				 * state unchanged so we don't inadvertently
				 * prevent attachment of any emulated device.
				 */
				xenbusb_delete_child(dev, kids[i]);

				/*
				 * Since the XenStore state of this device
				 * still indicates a pending attach, manually
				 * release it's hold on the boot process.
				 */
				xbs = device_get_softc(dev);
				xenbusb_release_confighook(xbs);

				continue;
			} else if (error) {
				/*
				 * Transition device to the closed state
				 * so the world knows that attachment will
				 * not occur.
				 */
				xenbus_set_state(kids[i], XenbusStateClosed);

				/*
				 * Remove our record of this device.
				 * So long as it remains in the closed
				 * state in the XenStore, we will not find
				 * it again.  The state will only change
				 * if the control domain actively reconfigures
				 * this device.
				 */
				xenbusb_delete_child(dev, kids[i]);

				continue;
			}
			/*
			 * Augment default newbus provided dynamic sysctl
			 * variables with the standard ivar contents of
			 * XenBus devices.
			 */
			xenbusb_device_sysctl_init(kids[i]);

			/*
			 * Now that we have a driver managing this device
			 * that can receive otherend state change events,
			 * hook up a watch for them.
			 */
			ivars = device_get_ivars(kids[i]);
			xs_register_watch(&ivars->xd_otherend_watch);
			xs_register_watch(&ivars->xd_local_watch);
		}
		free(kids, M_TEMP);
	}

	return (0);
}