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)

  • 相同,但它使用 filp->private_data 调用 v4l2_fh_is_singular。

2.6.1. V4L2 fh 函数和数据结构

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

序列化已订阅列表的更改; 保证按顺序调用添加和删除事件回调

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 添加到视频设备上的文件句柄列表。

参数

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)

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

参数

struct v4l2_fh *fh

指向 struct v4l2_fh 的指针

描述

如果 fh 为 NULL,则返回 0。

int v4l2_fh_is_singular_file(struct file *filp)

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

参数

struct file *filp

指向 struct file 的指针

描述

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

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