arch/um/drivers/ubd_kern.c

Source file repositories/reference/linux-study-clean/arch/um/drivers/ubd_kern.c

File Facts

System
Linux kernel
Corpus path
arch/um/drivers/ubd_kern.c
Extension
.c
Size
36109 bytes
Lines
1541
Domain
Architecture Layer
Bucket
arch/um
Inferred role
Architecture Layer: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct blk_mq_ops ubd_mq_ops = {
	.queue_rq = ubd_queue_rq,
};

static int ubd_add(int n, char **error_out)
{
	struct ubd *ubd_dev = &ubd_devs[n];
	struct queue_limits lim = {
		.max_segments		= MAX_SG,
		.seg_boundary_mask	= PAGE_SIZE - 1,
		.features		= BLK_FEAT_WRITE_CACHE,
	};
	struct gendisk *disk;
	int err = 0;

	if(ubd_dev->file == NULL)
		goto out;

	if (ubd_dev->cow.file)
		lim.max_hw_sectors = 8 * sizeof(long);
	if (!ubd_dev->no_trim) {
		lim.max_hw_discard_sectors = UBD_MAX_REQUEST;
		lim.max_write_zeroes_sectors = UBD_MAX_REQUEST;
	}

	err = ubd_file_size(ubd_dev, &ubd_dev->size);
	if(err < 0){
		*error_out = "Couldn't determine size of device's file";
		goto out;
	}

	err = ubd_open_dev(ubd_dev);
	if (err) {
		pr_err("ubd%c: Can't open \"%s\": errno = %d\n",
			'a' + n, ubd_dev->file, -err);
		goto out;
	}

	ubd_dev->size = ROUND_BLOCK(ubd_dev->size);

	ubd_dev->tag_set.ops = &ubd_mq_ops;
	ubd_dev->tag_set.queue_depth = 64;
	ubd_dev->tag_set.numa_node = NUMA_NO_NODE;
	ubd_dev->tag_set.driver_data = ubd_dev;
	ubd_dev->tag_set.nr_hw_queues = 1;

	err = blk_mq_alloc_tag_set(&ubd_dev->tag_set);
	if (err)
		goto out_close;

	disk = blk_mq_alloc_disk(&ubd_dev->tag_set, &lim, ubd_dev);
	if (IS_ERR(disk)) {
		err = PTR_ERR(disk);
		goto out_cleanup_tags;
	}

	disk->major = UBD_MAJOR;
	disk->first_minor = n << UBD_SHIFT;
	disk->minors = 1 << UBD_SHIFT;
	disk->fops = &ubd_blops;
	set_capacity(disk, ubd_dev->size / 512);
	sprintf(disk->disk_name, "ubd%c", 'a' + n);
	disk->private_data = ubd_dev;
	set_disk_ro(disk, !ubd_dev->openflags.w);

	ubd_dev->pdev.id = n;
	ubd_dev->pdev.name = DRIVER_NAME;
	ubd_dev->pdev.dev.release = ubd_device_release;
	dev_set_drvdata(&ubd_dev->pdev.dev, ubd_dev);
	platform_device_register(&ubd_dev->pdev);

	err = device_add_disk(&ubd_dev->pdev.dev, disk, ubd_attr_groups);
	if (err)
		goto out_cleanup_disk;

	ubd_dev->disk = disk;

	return 0;

out_cleanup_disk:
	put_disk(disk);
out_cleanup_tags:
	blk_mq_free_tag_set(&ubd_dev->tag_set);
out_close:
	ubd_close_dev(ubd_dev);
out:
	return err;
}

static int ubd_config(char *str, char **error_out)

Annotation

Implementation Notes