drivers/char/misc_minor_kunit.c

Source file repositories/reference/linux-study-clean/drivers/char/misc_minor_kunit.c

File Facts

System
Linux kernel
Corpus path
drivers/char/misc_minor_kunit.c
Extension
.c
Size
16785 bytes
Lines
690
Domain
Driver Families
Bucket
drivers/char
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations miscdev_test_fops = {
	.open	= miscdev_test_open,
};

static void __init miscdev_test_can_open(struct kunit *test, struct miscdevice *misc)
{
	int ret;
	struct file *filp;
	char *devname;

	devname = kasprintf(GFP_KERNEL, "/dev/%s", misc->name);
	ret = init_mknod(devname, S_IFCHR | 0600,
			 new_encode_dev(MKDEV(MISC_MAJOR, misc->minor)));
	if (ret != 0)
		KUNIT_FAIL(test, "failed to create node\n");

	filp = filp_open(devname, O_RDONLY, 0);
	if (IS_ERR(filp))
		KUNIT_FAIL(test, "failed to open misc device: %ld\n", PTR_ERR(filp));
	else
		fput(filp);

	init_unlink(devname);
	kfree(devname);
}

static void __init miscdev_test_static_basic(struct kunit *test)
{
	struct miscdevice misc_test = {
		.name = "misc_test",
		.fops = &miscdev_test_fops,
	};
	int ret;
	const struct miscdev_test_case *params = test->param_value;

	misc_test.minor = params->minor;

	ret = misc_register(&misc_test);
	KUNIT_EXPECT_EQ(test, ret, 0);
	KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor);

	if (ret == 0) {
		miscdev_test_can_open(test, &misc_test);
		misc_deregister(&misc_test);
	}
}

static void __init miscdev_test_dynamic_basic(struct kunit *test)
{
	struct miscdevice misc_test = {
		.minor = MISC_DYNAMIC_MINOR,
		.name = "misc_test",
		.fops = &miscdev_test_fops,
	};
	int ret;

	ret = misc_register(&misc_test);
	KUNIT_EXPECT_EQ(test, ret, 0);
	KUNIT_EXPECT_TRUE(test, is_valid_dynamic_minor(misc_test.minor));

	if (ret == 0) {
		miscdev_test_can_open(test, &misc_test);
		misc_deregister(&misc_test);
	}
}

static void miscdev_test_twice(struct kunit *test)
{
	struct miscdevice misc_test = {
		.name = "misc_test",
		.fops = &miscdev_test_fops,
	};
	int ret;
	const struct miscdev_test_case *params = test->param_value;

	misc_test.minor = params->minor;

	ret = misc_register(&misc_test);
	KUNIT_EXPECT_EQ(test, ret, 0);
	KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor);
	if (ret == 0)
		misc_deregister(&misc_test);

	ret = misc_register(&misc_test);
	KUNIT_EXPECT_EQ(test, ret, 0);
	KUNIT_EXPECT_EQ(test, misc_test.minor, params->minor);
	if (ret == 0)
		misc_deregister(&misc_test);
}

Annotation

Implementation Notes