Пример #1
0
static int blkback_remove(struct xenbus_device *dev)
{
	struct backend_info *be = dev->data;

	DPRINTK("");

	if (be->backend_watch.node) {
		unregister_xenbus_watch(&be->backend_watch);
		kfree(be->backend_watch.node);
		be->backend_watch.node = NULL;
	}
	if (be->blkif) {
		if (be->blkif->xenblkd)
			kthread_stop(be->blkif->xenblkd);
		blkif_free(be->blkif);
		be->blkif = NULL;
	}

	device_remove_file(&dev->dev, &dev_attr_physical_device);
	device_remove_file(&dev->dev, &dev_attr_mode);

	kfree(be);
	dev->data = NULL;
	return 0;
}
Пример #2
0
static int xen_blkbk_remove(struct xenbus_device *dev)
{
	struct backend_info *be = dev_get_drvdata(&dev->dev);

	DPRINTK("");

	if (be->major || be->minor)
		xenvbd_sysfs_delif(dev);

	if (be->backend_watch.node) {
		unregister_xenbus_watch(&be->backend_watch);
		kfree(be->backend_watch.node);
		be->backend_watch.node = NULL;
	}

	if (be->blkif) {
		xen_blkif_disconnect(be->blkif);
		xen_vbd_free(&be->blkif->vbd);
		xen_blkif_free(be->blkif);
		be->blkif = NULL;
	}

	kfree(be->mode);
	kfree(be);
	dev_set_drvdata(&dev->dev, NULL);
	return 0;
}
Пример #3
0
static void free_otherend_watch(struct xenbus_device *dev)
{
	if (dev->otherend_watch.node) {
		unregister_xenbus_watch(&dev->otherend_watch);
		kfree(dev->otherend_watch.node);
		dev->otherend_watch.node = NULL;
	}
}
Пример #4
0
Файл: xenbus.c Проект: gxt/linux
static void unregister_hotplug_status_watch(struct backend_info *be)
{
	if (be->have_hotplug_status_watch) {
		unregister_xenbus_watch(&be->hotplug_status_watch);
		kfree(be->hotplug_status_watch.node);
	}
	be->have_hotplug_status_watch = 0;
}
Пример #5
0
Файл: xenbus.c Проект: gxt/linux
static void xen_unregister_mcast_ctrl_watch(struct xenvif *vif)
{
	if (vif->mcast_ctrl_watch.node) {
		unregister_xenbus_watch(&vif->mcast_ctrl_watch);
		kfree(vif->mcast_ctrl_watch.node);
		vif->mcast_ctrl_watch.node = NULL;
	}
}
Пример #6
0
Файл: xenbus.c Проект: gxt/linux
static void xen_unregister_credit_watch(struct xenvif *vif)
{
	if (vif->credit_watch.node) {
		unregister_xenbus_watch(&vif->credit_watch);
		kfree(vif->credit_watch.node);
		vif->credit_watch.node = NULL;
	}
}
Пример #7
0
static void
free_otherend_watch(struct xenbus_device *dev)
{
	if (dev->otherend_watch.node) {
		unregister_xenbus_watch(&dev->otherend_watch);
		kmem_free((void *)dev->otherend_watch.node,
		    strlen(dev->otherend_watch.node) + 1);
		dev->otherend_watch.node = NULL;
	}
}
Пример #8
0
/* Asynch callback to check for /local/domain/<DOMID>/name */
static void check_dom(struct xs_handle *h, struct xenbus_watch *w, 
	       const char *bepath_im)
{
	char *domid;

	domid = get_dom_domid(h);
	if (domid == NULL)
		return;

	add_blockdevice_probe_watch(h, domid);
	free(domid);
	unregister_xenbus_watch(h, w);
}
Пример #9
0
static void free_pdev(struct xen_pcibk_device *pdev)
{
	if (pdev->be_watching) {
		unregister_xenbus_watch(&pdev->be_watch);
		pdev->be_watching = 0;
	}

	xen_pcibk_disconnect(pdev);

	xen_pcibk_release_devices(pdev);

	dev_set_drvdata(&pdev->xdev->dev, NULL);
	pdev->xdev = NULL;

	kfree(pdev);
}
Пример #10
0
static int netback_remove(struct xenbus_device *dev)
{
	struct backend_info *be = dev->data;

	if (be->backend_watch.node) {
		unregister_xenbus_watch(&be->backend_watch);
		kfree(be->backend_watch.node);
		be->backend_watch.node = NULL;
	}
	if (be->netif) {
		netif_disconnect(be->netif);
		be->netif = NULL;
	}
	kfree(be);
	dev->data = NULL;
	return 0;
}
Пример #11
0
static void free_pdev(struct xen_pcibk_device *pdev)
{
	if (pdev->be_watching) {
		unregister_xenbus_watch(&pdev->be_watch);
		pdev->be_watching = 0;
	}

	xen_pcibk_disconnect(pdev);

	/* N.B. This calls pcistub_put_pci_dev which does the FLR on all
	 * of the PCIe devices. */
	xen_pcibk_release_devices(pdev);

	dev_set_drvdata(&pdev->xdev->dev, NULL);
	pdev->xdev = NULL;

	kfree(pdev);
}
Пример #12
0
static int tpmback_remove(struct xenbus_device *dev)
{
	struct backend_info *be = dev->data;

	if (!be) return 0;

	if (be->backend_watch.node) {
		unregister_xenbus_watch(&be->backend_watch);
		kfree(be->backend_watch.node);
		be->backend_watch.node = NULL;
	}
	if (be->tpmif) {
		vtpm_release_packets(be->tpmif, 0);
		tpmif_put(be->tpmif);
		be->tpmif = NULL;
	}
	kfree(be);
	dev->data = NULL;
	return 0;
}
/*
 * Reset frontend if it is in Connected or Closed state.
 * Wait for backend to catch up.
 * State Connected happens during kdump, Closed after kexec.
 */
static void xenbus_reset_frontend(char *fe, char *be, int be_state)
{
	struct xenbus_watch be_watch;

	printk(KERN_DEBUG "XENBUS: backend %s %s\n",
			be, xenbus_strstate(be_state));

	memset(&be_watch, 0, sizeof(be_watch));
	be_watch.node = kasprintf(GFP_NOIO | __GFP_HIGH, "%s/state", be);
	if (!be_watch.node)
		return;

	be_watch.callback = xenbus_reset_backend_state_changed;
	backend_state = XenbusStateUnknown;

	printk(KERN_INFO "XENBUS: triggering reconnect on %s\n", be);
	register_xenbus_watch(&be_watch);

	/* fall through to forward backend to state XenbusStateInitialising */
	switch (be_state) {
	case XenbusStateConnected:
		xenbus_printf(XBT_NIL, fe, "state", "%d", XenbusStateClosing);
		xenbus_reset_wait_for_backend(be, XenbusStateClosing);

	case XenbusStateClosing:
		xenbus_printf(XBT_NIL, fe, "state", "%d", XenbusStateClosed);
		xenbus_reset_wait_for_backend(be, XenbusStateClosed);

	case XenbusStateClosed:
		xenbus_printf(XBT_NIL, fe, "state", "%d", XenbusStateInitialising);
		xenbus_reset_wait_for_backend(be, XenbusStateInitWait);
	}

	unregister_xenbus_watch(&be_watch);
	printk(KERN_INFO "XENBUS: reconnect done on %s\n", be);
	kfree(be_watch.node);
}
Пример #14
0
int netback_accel_remove(struct xenbus_device *dev)
{
	struct backend_info *binfo;
	struct netback_accel *bend; 
	int frontend_state;

	binfo = (struct backend_info *) dev->dev.driver_data;
	bend = (struct netback_accel *) binfo->netback_accel_priv;

	DPRINTK("%s: dev %p bend %p\n", __FUNCTION__, dev, bend);
	
	BUG_ON(bend == NULL);
	
	mutex_lock(&bend_list_mutex);
	unlink_bend(bend);
	mutex_unlock(&bend_list_mutex);

	mutex_lock(&bend->bend_mutex);

	/* Reject any requests to connect. */
	bend->removing = 1;

	/*
	 * Switch to closing to tell the other end that we're going
	 * away.
	 */
	if (bend->backend_state != XenbusStateClosing) {
		bend->backend_state = XenbusStateClosing;
		net_accel_update_state(dev, XenbusStateClosing);
	}

	frontend_state = (int)XenbusStateUnknown;
	xenbus_scanf(XBT_NIL, dev->otherend, "accelstate", "%d",
		     &frontend_state);

	mutex_unlock(&bend->bend_mutex);

	/*
	 * Wait until this end goes to the closed state.  This happens
	 * in response to the other end going to the closed state.
	 * Don't bother doing this if the other end is already closed
	 * because if it is then there is nothing to do.
	 */
	if (frontend_state != (int)XenbusStateClosed &&
	    frontend_state != (int)XenbusStateUnknown)
		wait_event(bend->state_wait_queue,
			   bend->backend_state == XenbusStateClosed);

	unregister_xenbus_watch(&bend->domu_accel_watch);
	kfree(bend->domu_accel_watch.node);

	unregister_xenbus_watch(&bend->config_accel_watch);
	kfree(bend->config_accel_watch.node);

	/*
	 * Flush the scheduled work queue before freeing bend to get
	 * rid of any pending netback_accel_msg_rx_handler()
	 */
	flush_scheduled_work();

	mutex_lock(&bend->bend_mutex);

	/* Tear down the vnic if it was set up. */
	if (bend->vnic_is_setup) {
		bend->vnic_is_setup = 0;
		cleanup_vnic(bend);
	}

	bend->backend_state = XenbusStateUnknown;
	net_accel_update_state(dev, XenbusStateUnknown);

	netback_accel_debugfs_remove(bend);

	unpublish_frontend_name(dev);

	kfree(bend->nicname);

	binfo->netback_accel_priv = NULL;

	mutex_unlock(&bend->bend_mutex);

	kfree(bend);

	return 0;
}
Пример #15
0
int netback_accel_probe(struct xenbus_device *dev)
{
	struct netback_accel *bend;
	struct backend_info *binfo;
	int err;

	DPRINTK("%s: passed device %s\n", __FUNCTION__, dev->nodename);

	/* Allocate structure to store all our state... */
	bend = kzalloc(sizeof(struct netback_accel), GFP_KERNEL);
	if (bend == NULL) {
		DPRINTK("%s: no memory for bend\n", __FUNCTION__);
		return -ENOMEM;
	}
	
	mutex_init(&bend->bend_mutex);

	mutex_lock(&bend->bend_mutex);

	/* ...and store it where we can get at it */
	binfo = (struct backend_info *) dev->dev.driver_data;
	binfo->netback_accel_priv = bend;
	/* And vice-versa */
	bend->hdev_data = dev;

	DPRINTK("%s: Adding bend %p to list\n", __FUNCTION__, bend);
	
	init_waitqueue_head(&bend->state_wait_queue);
	bend->vnic_is_setup = 0;
	bend->frontend_state = XenbusStateUnknown;
	bend->backend_state = XenbusStateClosed;
	bend->removing = 0;

	sscanf(dev->nodename, NODENAME_PATH_FMT, &bend->far_end, 
	       &bend->vif_num);

	err = read_nicname(dev, bend);
	if (err) {
		/*
		 * Technically not an error, just means we're not 
		 * supposed to accelerate this
		 */
		DPRINTK("failed to get device name\n");
		goto fail_nicname;
	}

	/*
	 * Look up the device name in the list of NICs provided by
	 * driverlink to get the hardware type.
	 */
	err = netback_accel_sf_hwtype(bend);
	if (err) {
		/*
		 * Technically not an error, just means we're not
		 * supposed to accelerate this, probably belongs to
		 * some other backend
		 */
		DPRINTK("failed to match device name\n");
		goto fail_init_type;
	}

	err = publish_frontend_name(dev);
	if (err)
		goto fail_publish;

	err = netback_accel_debugfs_create(bend);
	if (err)
		goto fail_debugfs;
	
	mutex_unlock(&bend->bend_mutex);

	err = setup_config_accel_watch(dev, bend);
	if (err)
		goto fail_config_watch;

	err = setup_domu_accel_watch(dev, bend);
	if (err)
		goto fail_domu_watch;

	/*
	 * Indicate to the other end that we're ready to start unless
	 * the watch has already fired.
	 */
	mutex_lock(&bend->bend_mutex);
	if (bend->backend_state == XenbusStateClosed) {
		bend->backend_state = XenbusStateInitialising;
		net_accel_update_state(dev, XenbusStateInitialising);
	}
	mutex_unlock(&bend->bend_mutex);

	mutex_lock(&bend_list_mutex);
	link_bend(bend);
	mutex_unlock(&bend_list_mutex);

	return 0;

fail_domu_watch:

	unregister_xenbus_watch(&bend->config_accel_watch);
	kfree(bend->config_accel_watch.node);
fail_config_watch:

	/*
	 * Flush the scheduled work queue before freeing bend to get
	 * rid of any pending netback_accel_msg_rx_handler()
	 */
	flush_scheduled_work();

	mutex_lock(&bend->bend_mutex);
	net_accel_update_state(dev, XenbusStateUnknown);
	netback_accel_debugfs_remove(bend);
fail_debugfs:

	unpublish_frontend_name(dev);
fail_publish:

	/* No need to reverse netback_accel_sf_hwtype. */
fail_init_type:

	kfree(bend->nicname);
fail_nicname:
	binfo->netback_accel_priv = NULL;
	mutex_unlock(&bend->bend_mutex);
	kfree(bend);
	return err;
}
static int
xenbus_resume(device_t dev)
{
	device_t *kids;
	struct xenbus_device_ivars *ivars;
	int i, count, error;
	char *statepath;

	xb_init_comms();
	xs_resume();

	/*
	 * We must re-examine each device and find the new path for
	 * its backend.
	 */
	if (device_get_children(dev, &kids, &count) == 0) {
		for (i = 0; i < count; i++) {
			if (device_get_state(kids[i]) == DS_NOTPRESENT)
				continue;

			ivars = device_get_ivars(kids[i]);

			unregister_xenbus_watch(
				&ivars->xd_otherend_watch);
			ivars->xd_state = XenbusStateInitialising;

			/*
			 * Find the new backend details and
			 * re-register our watch.
			 */
			free(ivars->xd_otherend_path, M_DEVBUF);
			error = xenbus_gather(XBT_NIL, ivars->xd_node,
			    "backend-id", "%i", &ivars->xd_otherend_id,
			    "backend", NULL, &ivars->xd_otherend_path,
			    NULL);
			if (error)
				return (error);

			DEVICE_RESUME(kids[i]);

			statepath = malloc(strlen(ivars->xd_otherend_path)
			    + strlen("/state") + 1, M_DEVBUF, M_WAITOK);
			sprintf(statepath, "%s/state", ivars->xd_otherend_path);

			free(ivars->xd_otherend_watch.node, M_DEVBUF);
			ivars->xd_otherend_watch.node = statepath;
			register_xenbus_watch(
				&ivars->xd_otherend_watch);

#if 0
			/*
			 * Can't do this yet since we are running in
			 * the xenwatch thread and if we sleep here,
			 * we will stop delivering watch notifications
			 * and the device will never come back online.
			 */
			sx_xlock(&ivars->xd_lock);
			while (ivars->xd_state != XenbusStateClosed
			    && ivars->xd_state != XenbusStateConnected)
				sx_sleep(&ivars->xd_state, &ivars->xd_lock,
				    0, "xdresume", 0);
			sx_xunlock(&ivars->xd_lock);
#endif
		}
		free(kids, M_TEMP);
	}

	return (0);
}