drivers/media/mc/mc-devnode.c

Source file repositories/reference/linux-study-clean/drivers/media/mc/mc-devnode.c

File Facts

System
Linux kernel
Corpus path
drivers/media/mc/mc-devnode.c
Extension
.c
Size
8445 bytes
Lines
327
Domain
Driver Families
Bucket
drivers/media
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 bus_type media_bus_type = {
	.name = MEDIA_NAME,
};

static ssize_t media_read(struct file *filp, char __user *buf,
		size_t sz, loff_t *off)
{
	struct media_devnode *devnode = media_devnode_data(filp);

	if (!devnode->fops->read)
		return -EINVAL;
	if (!media_devnode_is_registered(devnode))
		return -EIO;
	return devnode->fops->read(filp, buf, sz, off);
}

static ssize_t media_write(struct file *filp, const char __user *buf,
		size_t sz, loff_t *off)
{
	struct media_devnode *devnode = media_devnode_data(filp);

	if (!devnode->fops->write)
		return -EINVAL;
	if (!media_devnode_is_registered(devnode))
		return -EIO;
	return devnode->fops->write(filp, buf, sz, off);
}

static __poll_t media_poll(struct file *filp,
			       struct poll_table_struct *poll)
{
	struct media_devnode *devnode = media_devnode_data(filp);

	if (!media_devnode_is_registered(devnode))
		return EPOLLERR | EPOLLHUP;
	if (!devnode->fops->poll)
		return DEFAULT_POLLMASK;
	return devnode->fops->poll(filp, poll);
}

static long
__media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg,
	      long (*ioctl_func)(struct file *filp, unsigned int cmd,
				 unsigned long arg))
{
	struct media_devnode *devnode = media_devnode_data(filp);

	if (!ioctl_func)
		return -ENOTTY;

	if (!media_devnode_is_registered(devnode))
		return -EIO;

	return ioctl_func(filp, cmd, arg);
}

static long media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct media_devnode *devnode = media_devnode_data(filp);

	return __media_ioctl(filp, cmd, arg, devnode->fops->ioctl);
}

#ifdef CONFIG_COMPAT

static long media_compat_ioctl(struct file *filp, unsigned int cmd,
			       unsigned long arg)
{
	struct media_devnode *devnode = media_devnode_data(filp);

	return __media_ioctl(filp, cmd, arg, devnode->fops->compat_ioctl);
}

#endif /* CONFIG_COMPAT */

/* Override for the open function */
static int media_open(struct inode *inode, struct file *filp)
{
	struct media_devnode *devnode;
	int ret;

	/* Check if the media device is available. This needs to be done with
	 * the media_devnode_lock held to prevent an open/unregister race:
	 * without the lock, the device could be unregistered and freed between
	 * the media_devnode_is_registered() and get_device() calls, leading to
	 * a crash.
	 */
	mutex_lock(&media_devnode_lock);
	devnode = container_of(inode->i_cdev, struct media_devnode, cdev);
	/* return ENXIO if the media device has been removed

Annotation

Implementation Notes