2.6. V4L2 文件句柄

struct v4l2_fh 提供了一种轻松保存 V4L2 框架使用的特定于文件句柄的数据的方法。

注意

新的驱动程序必须使用 struct v4l2_fh,因为它也被用于实现优先级处理(ioctl VIDIOC_G_PRIORITY, VIDIOC_S_PRIORITY)。

v4l2_fh 的用户(在 V4L2 框架中,而不是驱动程序中)通过测试 video_device->flags 中的 V4L2_FL_USES_V4L2_FH 位来知道驱动程序是否使用 v4l2_fh 作为其 file->private_data 指针。当调用 v4l2_fh_init() 时,会设置此位。

struct v4l2_fh 作为驱动程序自己的文件句柄结构的一部分进行分配,并且 file->private_data 在驱动程序的 open() 函数中由驱动程序设置为它。

在许多情况下,struct v4l2_fh 将嵌入到更大的结构中。在这种情况下,您应该在 open() 中调用

  1. v4l2_fh_init()v4l2_fh_add()

  2. release() 中调用 v4l2_fh_del()v4l2_fh_exit()

驱动程序可以使用 container_of 宏来提取自己的文件句柄结构。

示例

struct my_fh {
        int blah;
        struct v4l2_fh fh;
};

...

int my_open(struct file *file)
{
        struct my_fh *my_fh;
        struct video_device *vfd;
        int ret;

        ...

        my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);

        ...

        v4l2_fh_init(&my_fh->fh, vfd);

        ...

        file->private_data = &my_fh->fh;
        v4l2_fh_add(&my_fh->fh);
        return 0;
}

int my_release(struct file *file)
{
        struct v4l2_fh *fh = file->private_data;
        struct my_fh *my_fh = container_of(fh, struct my_fh, fh);

        ...
        v4l2_fh_del(&my_fh->fh);
        v4l2_fh_exit(&my_fh->fh);
        kfree(my_fh);
        return 0;
}

以下是使用的 v4l2_fh 函数的简短描述

v4l2_fh_init (fh, vdev)

  • 初始化文件句柄。这 **必须** 在驱动程序的 v4l2_file_operations->open() 处理程序中执行。

v4l2_fh_add (fh)

  • v4l2_fh 添加到 video_device 文件句柄列表中。必须在文件句柄完全初始化后调用。

v4l2_fh_del (fh)

  • video_device 取消关联文件句柄。现在可以调用文件句柄退出函数。

v4l2_fh_exit (fh)

  • 取消初始化文件句柄。取消初始化后,可以释放 v4l2_fh 内存。

如果 struct v4l2_fh 未嵌入,则可以使用这些辅助函数

v4l2_fh_open (struct file *filp)

v4l2_fh_release (struct file *filp)

这两个函数可以插入到 v4l2_file_operation 的 open()release() 操作中。

当第一个文件句柄打开和最后一个文件句柄关闭时,一些驱动程序需要执行某些操作。添加了两个辅助函数来检查 v4l2_fh 结构是否是相关设备节点的唯一打开的文件句柄

v4l2_fh_is_singular (fh)

  • 如果文件句柄是唯一打开的文件句柄,则返回 1,否则返回 0。

v4l2_fh_is_singular_file (struct file *filp)

  • 相同,但它会调用 v4l2_fh_is_singular,使用 filp->private_data 作为参数。

2.6.1. V4L2 文件句柄函数和数据结构

struct v4l2_fh

描述一个 V4L2 文件句柄

定义:

struct v4l2_fh {
    struct list_head        list;
    struct video_device     *vdev;
    struct v4l2_ctrl_handler *ctrl_handler;
    enum v4l2_priority      prio;
    wait_queue_head_t wait;
    struct mutex            subscribe_lock;
    struct list_head        subscribed;
    struct list_head        available;
    unsigned int            navailable;
    u32 sequence;
    struct v4l2_m2m_ctx     *m2m_ctx;
};

成员

list

文件句柄列表

vdev

指向 struct video_device 的指针

ctrl_handler

指向 struct v4l2_ctrl_handler 的指针

prio

文件句柄的优先级,由 enum v4l2_priority 定义

wait

事件的等待队列

subscribe_lock

序列化已订阅列表的更改;保证 add 和 del 事件回调按顺序调用

subscribed

已订阅的事件列表

available

等待出队的事件列表

navailable

available 列表中可用事件的数量

sequence

事件序列号

m2m_ctx

指向 struct v4l2_m2m_ctx 的指针

void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)

初始化文件句柄。

参数

struct v4l2_fh *fh

指向 struct v4l2_fh 的指针

struct video_device *vdev

指向 struct video_device 的指针

描述

使用文件句柄的 V4L2 框架部分应在此函数中初始化。如果驱动程序使用 struct v4l2_fh,则必须从驱动程序的 v4l2_file_operations->open() 处理程序中调用此函数。

void v4l2_fh_add(struct v4l2_fh *fh)

将 fh 添加到 video_device 上的文件句柄列表。

参数

struct v4l2_fh *fh

指向 struct v4l2_fh 的指针

描述

注意

必须先初始化 fh 文件句柄。

int v4l2_fh_open(struct file *filp)

辅助例程,可用作 v4l2_file_operations 的 open() 操作。

参数

struct file *filp

指向 struct file 的指针

描述

它分配一个 v4l2_fh,并将其初始化并添加到与文件指针关联的 struct video_device 中。

void v4l2_fh_del(struct v4l2_fh *fh)

从文件句柄列表中删除文件句柄。

参数

struct v4l2_fh *fh

指向 struct v4l2_fh 的指针

描述

如果发生错误,filp->private_data 将为 NULL,否则它将指向 struct v4l2_fh

注意

如果驱动程序使用 struct v4l2_fh,则必须在 v4l2_file_operations->release() 处理程序中调用此函数。

void v4l2_fh_exit(struct v4l2_fh *fh)

释放与文件句柄相关的资源。

参数

struct v4l2_fh *fh

指向 struct v4l2_fh 的指针

描述

使用 v4l2_fh 的 V4L2 框架部分也必须在此处释放其资源。

注意

如果驱动程序使用 struct v4l2_fh,则必须在 v4l2_file_operations->release() 处理程序中调用此函数。

int v4l2_fh_release(struct file *filp)

辅助例程,可用作 v4l2_file_operations 的 release() 操作。

参数

struct file *filp

指向 struct file 的指针

描述

它删除并退出与文件指针关联的 v4l2_fh 并释放它。如果 filp->private_data(指向 v4l2_fh 结构的指针)为 NULL,则它将不执行任何操作。

此函数始终返回 0。

int v4l2_fh_is_singular(struct v4l2_fh *fh)

如果此文件句柄是为关联的 video_device 打开的唯一文件句柄,则返回 1。

参数

struct v4l2_fh *fh

指向 struct v4l2_fh 的指针

描述

如果 fh 为 NULL,则返回 0。

int v4l2_fh_is_singular_file(struct file *filp)

如果此文件句柄是为关联的 video_device 打开的唯一文件句柄,则返回 1。

参数

struct file *filp

指向 struct file 的指针

描述

这是 v4l2_fh_is_singular() 的一个辅助函数变体,它使用 struct file 作为参数。

如果 filp->private_data 为 NULL,则它将返回 0。