node-drivers/base-driver/drivers/vca/blockio/vcablk/vcablk_disk.c
struct vcablk_disk *
vcablk_disk_create(struct vcablk_dev* fdev, int uniq_id, size_t size, bool read_only,
		struct vcablk_ring *ring_req, struct vcablk_ring *completion_ring,
		int bio_done_db, int request_db)
{
	int err = 0;
	struct gendisk *disk = NULL;
	struct vcablk_disk *dev = NULL;
	unsigned sectors_num;
	int hardsect_size;

	if (!ring_req) {
		pr_err("%s: Disk with ID %i ring_req is NULL\n", __func__, uniq_id);
		err = -EFAULT;
		goto exit;
	}

	if (!completion_ring) {
		pr_err("%s: Disk with ID %i completion_ring is NULL\n", __func__, uniq_id);
		err = -EFAULT;
		goto exit;
	}

	if (request_db < 0) {
		pr_err("%s: Disk with ID %i irq_request is NULL\n", __func__, uniq_id);
		err = -EFAULT;
		goto exit;
	}

	hardsect_size = SECTOR_SIZE;
	sectors_num = size / hardsect_size;
	if (size % hardsect_size) {
		pr_warn("%s: size %lu is not multiple of sector size %i\n",
				__func__, size, hardsect_size);
		err = -ENOTBLK;
		goto exit;
	}

	dev = kmalloc(sizeof (struct vcablk_disk), GFP_KERNEL);
	if (dev == NULL) {
		pr_err("%s: Can not allocate device size %lu\n", __func__,
				sizeof (struct vcablk_disk));
		err = -ENOMEM;
		goto exit;
	}
	memset (dev, 0, sizeof (struct vcablk_disk));
	spin_lock_init(&dev->lock);
	dev->fdev = fdev;

	dev->bio_done_db = bio_done_db;

	if (dev->bio_done_db < 0) {
		pr_err("%s: Can not get Doorbell\n", __func__);
		err = -ENODEV;
		goto err;
	}

	init_waitqueue_head(&dev->resource_pool_wq);
	dev->bio_context_pool = vcablk_pool_init(VCABLK_BIO_CTX_POOL_SIZE,
			sizeof (struct vcablk_bio_context));
	if (!dev->bio_context_pool) {
		err =-ENOMEM;
		goto err;
	}

	dev->bvec_context_pool = vcablk_pool_init(VCABLK_BVEC_MAP_POOL_SIZE,
			sizeof (struct bvec_context));
	if (!dev->bvec_context_pool) {
		err =-ENOMEM;
		goto err;
	}

	dev->bio_done_irq =
			fdev->hw_ops->request_irq(fdev->parent, vcablk_disk_ack_irq,
					"IRQ_DONE_ACK", dev, dev->bio_done_db);

	if (IS_ERR(dev->bio_done_irq)) {
		dev->bio_done_irq = NULL;
		err =-EIO;
		goto err;
	}

	/* Set size of disk */
	dev->hardsect_size = hardsect_size; /* Base size of block */
	dev->sectors_num = sectors_num;
	dev->size_bytes = (size_t)dev->sectors_num * dev->hardsect_size;

	/* Set geometry of disk,some standard values, multiple of 512 */
	dev->geo.start = 0;
	dev->geo.heads = 1<<4;
	dev->geo.sectors = 1<<5;
	dev->geo.cylinders = dev->size_bytes>>9;

	pr_err("%s: Create disk dev_id %i size  %lu sectors_num %u "
			"hardsect_size %i heads %u sectors %u cylinders %u\n", __func__,
			uniq_id, dev->size_bytes, dev->sectors_num, dev->hardsect_size,
			dev->geo.heads, dev->geo.sectors, dev->geo.cylinders);

	dev->read_only = read_only;
	dev->dev_id = uniq_id;

	dev->request_bio_count = 0;
	bio_list_init(&dev->request_bio_list);
	init_waitqueue_head(&dev->request_wait);
	init_waitqueue_head(&dev->request_event);

	disk = dev->gdisk = alloc_disk(VCA_BLK_MINORS);
	if (!disk) {
		pr_err("%s: alloc_disk failure\n", __func__);
		err = -ENOMEM;
		goto err;
	}

	/* The I/O queue */
	disk->queue = dev->queue = blk_alloc_queue(GFP_KERNEL);
	if (dev->queue == NULL) {
		pr_err("%s: Can not allocate queue!\n", __func__);
		err = -ENOMEM;
		goto err;
	}

	/*
	 * set queue make_request_fn
	 */
	blk_queue_make_request(dev->queue, vcablk_disk_make_request);
	blk_queue_logical_block_size(dev->queue, dev->hardsect_size);
	dev->queue->queuedata = dev;

	disk->major = vcablk_major;
	disk->first_minor = uniq_id * VCA_BLK_MINORS;
	disk->fops = &vcablk_ops;
	disk->private_data = dev;
	set_capacity(disk, dev->sectors_num*(dev->hardsect_size>>SECTOR_SHIFT));
	set_disk_ro(disk, read_only);

	err = vcablk_disk_format_name(VCA_BLK_DISK_NAME, uniq_id, disk->disk_name,
			DISK_NAME_LEN);
	if (err) {
		pr_err("%s: disk (vcablk) name length exceeded\n", __func__);
		goto err;
	}

	INIT_WORK(&dev->request_completion_work, vcablk_disk_request_completion_handler);

	dev->request_ring = ring_req;
	dev->request_ring_alloc = ring_req->last_add;
	dev->completion_ring = completion_ring;
	dev->request_db = request_db;

	dev->gdisk_started = false;

	//MOVED TO START
	dev->request_thread = kthread_create(vcablk_disk_make_request_thread, dev,
			disk->disk_name);
	if (IS_ERR(dev->request_thread)) {
		pr_err("%s: Can not create thread %i\n", __func__,
				(int)PTR_ERR(dev->request_thread));
		dev->request_thread = NULL;
		err = -EAGAIN;
		goto err;
	}

	wake_up_process(dev->request_thread);
	return dev;
err:
	vcablk_disk_destroy(dev);
exit:
	return ERR_PTR(err);
}
/*
 * Set up our internal device.
 * size - Size of device in bytes
 */
Set up our internal device.
size - Size of device in bytes
Set up our internal device . size - Size of device in bytes
struct vcablk_disk *
vcablk_disk_create(struct vcablk_dev* fdev, int uniq_id, size_t size, bool read_only,
		struct vcablk_ring *ring_req, struct vcablk_ring *completion_ring,
		int bio_done_db, int request_db)
{
	int err = 0;
	struct gendisk *disk = NULL;
	struct vcablk_disk *dev = NULL;
	unsigned sectors_num;
	int hardsect_size;
	if (!ring_req) {
		pr_err("%s: Disk with ID %i ring_req is NULL\n", __func__, uniq_id);
		err = -EFAULT;
		goto exit;
	}
	if (!completion_ring) {
		pr_err("%s: Disk with ID %i completion_ring is NULL\n", __func__, uniq_id);
		err = -EFAULT;
		goto exit;
	}
	if (request_db < 0) {
		pr_err("%s: Disk with ID %i irq_request is NULL\n", __func__, uniq_id);
		err = -EFAULT;
		goto exit;
	}
	hardsect_size = SECTOR_SIZE;
	sectors_num = size / hardsect_size;
	if (size % hardsect_size) {
		pr_warn("%s: size %lu is not multiple of sector size %i\n",
				__func__, size, hardsect_size);
		err = -ENOTBLK;
		goto exit;
	}
	dev = kmalloc(sizeof (struct vcablk_disk), GFP_KERNEL);
	if (dev == NULL) {
		pr_err("%s: Can not allocate device size %lu\n", __func__,
				sizeof (struct vcablk_disk));
		err = -ENOMEM;
		goto exit;
	}
	memset (dev, 0, sizeof (struct vcablk_disk));
	spin_lock_init(&dev->lock);
	dev->fdev = fdev;
	dev->bio_done_db = bio_done_db;
	if (dev->bio_done_db < 0) {
		pr_err("%s: Can not get Doorbell\n", __func__);
		err = -ENODEV;
		goto err;
	}
	init_waitqueue_head(&dev->resource_pool_wq);
	dev->bio_context_pool = vcablk_pool_init(VCABLK_BIO_CTX_POOL_SIZE,
			sizeof (struct vcablk_bio_context));
	if (!dev->bio_context_pool) {
		err =-ENOMEM;
		goto err;
	}
	dev->bvec_context_pool = vcablk_pool_init(VCABLK_BVEC_MAP_POOL_SIZE,
			sizeof (struct bvec_context));
	if (!dev->bvec_context_pool) {
		err =-ENOMEM;
		goto err;
	}
	dev->bio_done_irq =
			fdev->hw_ops->request_irq(fdev->parent, vcablk_disk_ack_irq,
					"IRQ_DONE_ACK", dev, dev->bio_done_db);
	if (IS_ERR(dev->bio_done_irq)) {
		dev->bio_done_irq = NULL;
		err =-EIO;
		goto err;
	}
	dev->hardsect_size = hardsect_size; 
	dev->sectors_num = sectors_num;
	dev->size_bytes = (size_t)dev->sectors_num * dev->hardsect_size;
	dev->geo.start = 0;
	dev->geo.heads = 1<<4;
	dev->geo.sectors = 1<<5;
	dev->geo.cylinders = dev->size_bytes>>9;
	pr_err("%s: Create disk dev_id %i size  %lu sectors_num %u "
			"hardsect_size %i heads %u sectors %u cylinders %u\n", __func__,
			uniq_id, dev->size_bytes, dev->sectors_num, dev->hardsect_size,
			dev->geo.heads, dev->geo.sectors, dev->geo.cylinders);
	dev->read_only = read_only;
	dev->dev_id = uniq_id;
	dev->request_bio_count = 0;
	bio_list_init(&dev->request_bio_list);
	init_waitqueue_head(&dev->request_wait);
	init_waitqueue_head(&dev->request_event);
	disk = dev->gdisk = alloc_disk(VCA_BLK_MINORS);
	if (!disk) {
		pr_err("%s: alloc_disk failure\n", __func__);
		err = -ENOMEM;
		goto err;
	}
	disk->queue = dev->queue = blk_alloc_queue(GFP_KERNEL);
	if (dev->queue == NULL) {
		pr_err("%s: Can not allocate queue!\n", __func__);
		err = -ENOMEM;
		goto err;
	}
	blk_queue_make_request(dev->queue, vcablk_disk_make_request);
	blk_queue_logical_block_size(dev->queue, dev->hardsect_size);
	dev->queue->queuedata = dev;
	disk->major = vcablk_major;
	disk->first_minor = uniq_id * VCA_BLK_MINORS;
	disk->fops = &vcablk_ops;
	disk->private_data = dev;
	set_capacity(disk, dev->sectors_num*(dev->hardsect_size>>SECTOR_SHIFT));
	set_disk_ro(disk, read_only);
	err = vcablk_disk_format_name(VCA_BLK_DISK_NAME, uniq_id, disk->disk_name,
			DISK_NAME_LEN);
	if (err) {
		pr_err("%s: disk (vcablk) name length exceeded\n", __func__);
		goto err;
	}
	INIT_WORK(&dev->request_completion_work, vcablk_disk_request_completion_handler);
	dev->request_ring = ring_req;
	dev->request_ring_alloc = ring_req->last_add;
	dev->completion_ring = completion_ring;
	dev->request_db = request_db;
	dev->gdisk_started = false;
	dev->request_thread = kthread_create(vcablk_disk_make_request_thread, dev,
			disk->disk_name);
	if (IS_ERR(dev->request_thread)) {
		pr_err("%s: Can not create thread %i\n", __func__,
				(int)PTR_ERR(dev->request_thread));
		dev->request_thread = NULL;
		err = -EAGAIN;
		goto err;
	}
	wake_up_process(dev->request_thread);
	return dev;
err:
	vcablk_disk_destroy(dev);
exit:
	return ERR_PTR(err);
}
struct vcablk_disk * vcablk_disk_create ( struct vcablk_dev * fdev , int uniq_id , size_t size , bool read_only , struct vcablk_ring * ring_req , struct vcablk_ring * completion_ring , int bio_done_db , int request_db ) { int err = 0 ; struct gendisk * disk = NULL ; struct vcablk_disk * dev = NULL ; unsigned sectors_num ; int hardsect_size ; if ( ! ring_req ) { pr_err ( " \n " , __func__ , uniq_id ) ; err = - EFAULT ; goto exit ; } if ( ! completion_ring ) { pr_err ( " \n " , __func__ , uniq_id ) ; err = - EFAULT ; goto exit ; } if ( request_db < 0 ) { pr_err ( " \n " , __func__ , uniq_id ) ; err = - EFAULT ; goto exit ; } hardsect_size = SECTOR_SIZE ; sectors_num = size / hardsect_size ; if ( size % hardsect_size ) { pr_warn ( " \n " , __func__ , size , hardsect_size ) ; err = - ENOTBLK ; goto exit ; } dev = kmalloc ( sizeof ( struct vcablk_disk ) , GFP_KERNEL ) ; if ( dev == NULL ) { pr_err ( " \n " , __func__ , sizeof ( struct vcablk_disk ) ) ; err = - ENOMEM ; goto exit ; } memset ( dev , 0 , sizeof ( struct vcablk_disk ) ) ; spin_lock_init ( & dev -> lock ) ; dev -> fdev = fdev ; dev -> bio_done_db = bio_done_db ; if ( dev -> bio_done_db < 0 ) { pr_err ( " \n " , __func__ ) ; err = - ENODEV ; goto err ; } init_waitqueue_head ( & dev -> resource_pool_wq ) ; dev -> bio_context_pool = vcablk_pool_init ( VCABLK_BIO_CTX_POOL_SIZE , sizeof ( struct vcablk_bio_context ) ) ; if ( ! dev -> bio_context_pool ) { err = - ENOMEM ; goto err ; } dev -> bvec_context_pool = vcablk_pool_init ( VCABLK_BVEC_MAP_POOL_SIZE , sizeof ( struct bvec_context ) ) ; if ( ! dev -> bvec_context_pool ) { err = - ENOMEM ; goto err ; } dev -> bio_done_irq = fdev -> hw_ops -> request_irq ( fdev -> parent , vcablk_disk_ack_irq , " " , dev , dev -> bio_done_db ) ; if ( IS_ERR ( dev -> bio_done_irq ) ) { dev -> bio_done_irq = NULL ; err = - EIO ; goto err ; } dev -> hardsect_size = hardsect_size ; dev -> sectors_num = sectors_num ; dev -> size_bytes = ( size_t ) dev -> sectors_num * dev -> hardsect_size ; dev -> geo . start = 0 ; dev -> geo . heads = 1 << 4 ; dev -> geo . sectors = 1 << 5 ; dev -> geo . cylinders = dev -> size_bytes >> 9 ; pr_err ( " " " \n " , __func__ , uniq_id , dev -> size_bytes , dev -> sectors_num , dev -> hardsect_size , dev -> geo . heads , dev -> geo . sectors , dev -> geo . cylinders ) ; dev -> read_only = read_only ; dev -> dev_id = uniq_id ; dev -> request_bio_count = 0 ; bio_list_init ( & dev -> request_bio_list ) ; init_waitqueue_head ( & dev -> request_wait ) ; init_waitqueue_head ( & dev -> request_event ) ; disk = dev -> gdisk = alloc_disk ( VCA_BLK_MINORS ) ; if ( ! disk ) { pr_err ( " \n " , __func__ ) ; err = - ENOMEM ; goto err ; } disk -> queue = dev -> queue = blk_alloc_queue ( GFP_KERNEL ) ; if ( dev -> queue == NULL ) { pr_err ( " \n " , __func__ ) ; err = - ENOMEM ; goto err ; } blk_queue_make_request ( dev -> queue , vcablk_disk_make_request ) ; blk_queue_logical_block_size ( dev -> queue , dev -> hardsect_size ) ; dev -> queue -> queuedata = dev ; disk -> major = vcablk_major ; disk -> first_minor = uniq_id * VCA_BLK_MINORS ; disk -> fops = & vcablk_ops ; disk -> private_data = dev ; set_capacity ( disk , dev -> sectors_num * ( dev -> hardsect_size >> SECTOR_SHIFT ) ) ; set_disk_ro ( disk , read_only ) ; err = vcablk_disk_format_name ( VCA_BLK_DISK_NAME , uniq_id , disk -> disk_name , DISK_NAME_LEN ) ; if ( err ) { pr_err ( " \n " , __func__ ) ; goto err ; } INIT_WORK ( & dev -> request_completion_work , vcablk_disk_request_completion_handler ) ; dev -> request_ring = ring_req ; dev -> request_ring_alloc = ring_req -> last_add ; dev -> completion_ring = completion_ring ; dev -> request_db = request_db ; dev -> gdisk_started = false ; dev -> request_thread = kthread_create ( vcablk_disk_make_request_thread , dev , disk -> disk_name ) ; if ( IS_ERR ( dev -> request_thread ) ) { pr_err ( " \n " , __func__ , ( int ) PTR_ERR ( dev -> request_thread ) ) ; dev -> request_thread = NULL ; err = - EAGAIN ; goto err ; } wake_up_process ( dev -> request_thread ) ; return dev ; err : vcablk_disk_destroy ( dev ) ; exit : return ERR_PTR ( err ) ; }
Set up our internal device.
Set up our internal device .
/* Set size of disk */ /* Base size of block */ /* Set geometry of disk,some standard values, multiple of 512 */ /* The I/O queue */ /*
	 * set queue make_request_fn
	 */ //MOVED TO START