drivers/char/mem.c

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

File Facts

System
Linux kernel
Corpus path
drivers/char/mem.c
Extension
.c
Size
17026 bytes
Lines
779
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 __maybe_unused mem_fops = {
	.llseek		= memory_lseek,
	.read		= read_mem,
	.write		= write_mem,
	.mmap_prepare	= mmap_mem_prepare,
	.open		= open_mem,
#ifndef CONFIG_MMU
	.get_unmapped_area = get_unmapped_area_mem,
	.mmap_capabilities = memory_mmap_capabilities,
#endif
	.fop_flags	= FOP_UNSIGNED_OFFSET,
};

static const struct file_operations null_fops = {
	.llseek		= null_lseek,
	.read		= read_null,
	.write		= write_null,
	.read_iter	= read_iter_null,
	.write_iter	= write_iter_null,
	.splice_write	= splice_write_null,
	.uring_cmd	= uring_cmd_null,
};

#ifdef CONFIG_DEVPORT
static const struct file_operations port_fops = {
	.llseek		= memory_lseek,
	.read		= read_port,
	.write		= write_port,
	.open		= open_port,
};
#endif

static const struct file_operations zero_fops = {
	.llseek		= zero_lseek,
	.write		= write_zero,
	.read_iter	= read_iter_zero,
	.read		= read_zero,
	.write_iter	= write_iter_zero,
	.splice_read	= copy_splice_read,
	.splice_write	= splice_write_zero,
	.mmap_prepare	= mmap_zero_prepare,
	.get_unmapped_area = get_unmapped_area_zero,
#ifndef CONFIG_MMU
	.mmap_capabilities = zero_mmap_capabilities,
#endif
};

static const struct file_operations full_fops = {
	.llseek		= full_lseek,
	.read_iter	= read_iter_zero,
	.write		= write_full,
	.splice_read	= copy_splice_read,
};

static const struct memdev {
	const char *name;
	const struct file_operations *fops;
	fmode_t fmode;
	umode_t mode;
} devlist[] = {
#ifdef CONFIG_DEVMEM
	[DEVMEM_MINOR] = { "mem", &mem_fops, 0, 0 },
#endif
	[3] = { "null", &null_fops, FMODE_NOWAIT, 0666 },
#ifdef CONFIG_DEVPORT
	[4] = { "port", &port_fops, 0, 0 },
#endif
	[5] = { "zero", &zero_fops, FMODE_NOWAIT, 0666 },
	[7] = { "full", &full_fops, 0, 0666 },
	[8] = { "random", &random_fops, FMODE_NOWAIT, 0666 },
	[9] = { "urandom", &urandom_fops, FMODE_NOWAIT, 0666 },
#ifdef CONFIG_PRINTK
	[11] = { "kmsg", &kmsg_fops, 0, 0644 },
#endif
};

static int memory_open(struct inode *inode, struct file *filp)
{
	int minor;
	const struct memdev *dev;

	minor = iminor(inode);
	if (minor >= ARRAY_SIZE(devlist))
		return -ENXIO;

	dev = &devlist[minor];
	if (!dev->fops)
		return -ENXIO;

	filp->f_op = dev->fops;

Annotation

Implementation Notes