void rbd_destroy(struct rbd *d) { vmm_host_ram_reserve(d->addr, d->size); vmm_blockdev_unregister(d->bdev); vmm_blockdev_free(d->bdev); vmm_free(d); }
static struct rbd *__rbd_create(struct vmm_device *dev, const char *name, physical_addr_t pa, physical_size_t sz) { struct rbd *d; if (!name) { return NULL; } d = vmm_zalloc(sizeof(struct rbd)); if (!d) { goto free_nothing; } d->addr = pa; d->size = sz; d->bdev = vmm_blockdev_alloc(); if (!d->bdev) { goto free_rbd; } /* Setup block device instance */ strncpy(d->bdev->name, name, VMM_FIELD_NAME_SIZE); strncpy(d->bdev->desc, "RAM backed block device", VMM_FIELD_DESC_SIZE); d->bdev->dev = dev; d->bdev->flags = VMM_BLOCKDEV_RW; d->bdev->start_lba = 0; d->bdev->num_blocks = udiv64(d->size, RBD_BLOCK_SIZE); d->bdev->block_size = RBD_BLOCK_SIZE; /* Setup request queue for block device instance */ d->bdev->rq->make_request = rbd_make_request; d->bdev->rq->abort_request = rbd_abort_request; d->bdev->rq->priv = d; /* Register block device instance */ if (vmm_blockdev_register(d->bdev)) { goto free_bdev; } /* Reserve RAM space */ if (vmm_host_ram_reserve(d->addr, d->size)) { goto unreg_bdev; } return d; unreg_bdev: vmm_blockdev_unregister(d->bdev); free_bdev: vmm_blockdev_free(d->bdev); free_rbd: vmm_free(d); free_nothing: return NULL; }
void mtdblock_remove(struct mtd_info *mtd) { struct vmm_blockdev *bdev = NULL; struct vmm_blockrq *brq = NULL; if (NULL == (bdev = vmm_blockdev_find(mtd->name))) return; brq = vmm_blockrq_from_rq(bdev->rq); vmm_blockdev_unregister(bdev); if (brq) vmm_blockrq_destroy(brq); vmm_blockdev_free(bdev); }
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; }