Exemplo n.º 1
0
int vmm_blockdev_register(struct vmm_blockdev *bdev)
{
	int rc;
	struct vmm_classdev *cd;
	struct vmm_blockdev_event event;

	if (!bdev) {
		return VMM_EFAIL;
	}

	if (!(bdev->flags & VMM_BLOCKDEV_RDONLY) &&
	    !(bdev->flags & VMM_BLOCKDEV_RW)) {
		return VMM_EINVALID;
	}

	cd = vmm_malloc(sizeof(struct vmm_classdev));
	if (!cd) {
		rc = VMM_ENOMEM;
		goto fail;
	}

	INIT_LIST_HEAD(&cd->head);
	if (strlcpy(cd->name, bdev->name, sizeof(cd->name)) >=
	    sizeof(cd->name)) {
		rc = VMM_EOVERFLOW;
		goto free_classdev;
	}
	cd->dev = bdev->dev;
	cd->priv = bdev;

	rc = vmm_devdrv_register_classdev(VMM_BLOCKDEV_CLASS_NAME, cd);
	if (rc) {
		goto free_classdev;
	}

	/* Broadcast register event */
	event.bdev = bdev;
	event.data = NULL;
	vmm_blocking_notifier_call(&bdev_notifier_chain, 
				   VMM_BLOCKDEV_EVENT_REGISTER, 
				   &event);

	return VMM_OK;

free_classdev:
	vmm_free(cd);
fail:
	return rc;
}
Exemplo n.º 2
0
int vmm_blockdev_unregister(struct vmm_blockdev *bdev)
{
	int rc;
	struct dlist *l;
	struct vmm_blockdev *child_bdev;
	struct vmm_blockdev_event event;
	struct vmm_classdev *cd;

	if (!bdev) {
		return VMM_EFAIL;
	}

	/* Unreg & free child block devices */
	vmm_mutex_lock(&bdev->child_lock);
	while (!list_empty(&bdev->child_list)) {
		l = list_pop(&bdev->child_list);
		child_bdev = list_entry(l, struct vmm_blockdev, head);
		if ((rc = vmm_blockdev_unregister(child_bdev))) {
			vmm_mutex_unlock(&bdev->child_lock);
			return rc;
		}
		__blockdev_free(child_bdev, FALSE);
	}
	vmm_mutex_unlock(&bdev->child_lock);

	/* Broadcast unregister event */
	event.bdev = bdev;
	event.data = NULL;
	vmm_blocking_notifier_call(&bdev_notifier_chain, 
				   VMM_BLOCKDEV_EVENT_UNREGISTER, 
				   &event);

	cd = vmm_devdrv_find_classdev(VMM_BLOCKDEV_CLASS_NAME, bdev->name);
	if (!cd) {
		return VMM_EFAIL;
	}

	rc = vmm_devdrv_unregister_classdev(VMM_BLOCKDEV_CLASS_NAME, cd);
	if (!rc) {
		vmm_free(cd);
	}

	return rc;
}
Exemplo n.º 3
0
/**
 * Notify clients of fb_events
 */
int fb_notifier_call_chain(unsigned long val, void *v)
{
	return vmm_blocking_notifier_call(&fb_notifier_list, val, v);
}