2018-08-30 17:20:04 +03:00
.. SPDX-License-Identifier: GPL-2.0
2016-07-22 15:10:20 +03:00
V4L2 File handlers
------------------
2016-07-22 15:31:16 +03:00
struct :c:type: `v4l2_fh` provides a way to easily keep file handle specific
data that is used by the V4L2 framework.
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
.. attention ::
New drivers must use struct :c:type: `v4l2_fh`
since it is also used to implement priority handling
(:ref: `VIDIOC_G_PRIORITY` ).
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
The users of :c:type: `v4l2_fh` (in the V4L2 framework, not the driver) know
whether a driver uses :c:type: `v4l2_fh` as its `` file->private_data `` pointer
by testing the `` V4L2_FL_USES_V4L2_FH `` bit in :c:type: `video_device` ->flags.
2016-07-23 13:21:06 +03:00
This bit is set whenever :c:func: `v4l2_fh_init` is called.
2016-07-22 15:31:16 +03:00
struct :c:type: `v4l2_fh` is allocated as a part of the driver's own file handle
structure and `` file->private_data `` is set to it in the driver's `` open() ``
2016-07-22 15:10:20 +03:00
function by the driver.
2016-07-22 15:31:16 +03:00
In many cases the struct :c:type: `v4l2_fh` will be embedded in a larger
structure. In that case you should call:
2016-08-19 18:00:43 +03:00
#) :c:func: `v4l2_fh_init` and :c:func: `v4l2_fh_add` in `` open() ``
#) :c:func: `v4l2_fh_del` and :c:func: `v4l2_fh_exit` in `` release() ``
2016-07-22 15:10:20 +03:00
Drivers can extract their own file handle structure by using the container_of
2016-07-22 15:31:16 +03:00
macro.
Example:
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
.. code-block :: c
2016-07-22 15:10:20 +03:00
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;
}
2016-07-22 15:31:16 +03:00
Below is a short description of the :c:type: `v4l2_fh` functions used:
2016-07-22 15:10:20 +03:00
2016-07-23 13:21:06 +03:00
:c:func: `v4l2_fh_init <v4l2_fh_init>`
2016-07-22 15:31:16 +03:00
(:c:type: `fh <v4l2_fh>` , :c:type: `vdev <video_device>` )
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
- Initialise the file handle. This **MUST** be performed in the driver's
:c:type: `v4l2_file_operations` ->open() handler.
2016-07-22 15:10:20 +03:00
2016-07-23 13:21:06 +03:00
:c:func: `v4l2_fh_add <v4l2_fh_add>`
2016-07-22 15:31:16 +03:00
(:c:type: `fh <v4l2_fh>` )
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
- Add a :c:type: `v4l2_fh` to :c:type: `video_device` file handle list.
Must be called once the file handle is completely initialized.
2016-07-22 15:10:20 +03:00
2016-07-23 13:21:06 +03:00
:c:func: `v4l2_fh_del <v4l2_fh_del>`
2016-07-22 15:31:16 +03:00
(:c:type: `fh <v4l2_fh>` )
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
- Unassociate the file handle from :c:type: `video_device` . The file handle
2016-07-22 15:10:20 +03:00
exit function may now be called.
2016-07-23 13:21:06 +03:00
:c:func: `v4l2_fh_exit <v4l2_fh_exit>`
2016-07-22 15:31:16 +03:00
(:c:type: `fh <v4l2_fh>` )
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
- Uninitialise the file handle. After uninitialisation the :c:type: `v4l2_fh`
2016-07-22 15:10:20 +03:00
memory can be freed.
2016-07-22 15:31:16 +03:00
If struct :c:type: `v4l2_fh` is not embedded, then you can use these helper functions:
2016-07-22 15:10:20 +03:00
2016-07-23 13:21:06 +03:00
:c:func: `v4l2_fh_open <v4l2_fh_open>`
2016-07-22 15:31:16 +03:00
(struct file \*filp)
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
- This allocates a struct :c:type: `v4l2_fh` , initializes it and adds it to
the struct :c:type: `video_device` associated with the file struct.
2016-07-22 15:10:20 +03:00
2016-07-23 13:21:06 +03:00
:c:func: `v4l2_fh_release <v4l2_fh_release>`
2016-07-22 15:31:16 +03:00
(struct file \*filp)
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
- This deletes it from the struct :c:type: `video_device` associated with the
file struct, uninitialised the :c:type: `v4l2_fh` and frees it.
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
These two functions can be plugged into the v4l2_file_operation's `` open() ``
and `` release() `` ops.
2016-07-22 15:10:20 +03:00
Several drivers need to do something when the first file handle is opened and
when the last file handle closes. Two helper functions were added to check
2016-07-22 15:31:16 +03:00
whether the :c:type: `v4l2_fh` struct is the only open filehandle of the
associated device node:
2016-07-22 15:10:20 +03:00
2016-07-23 13:21:06 +03:00
:c:func: `v4l2_fh_is_singular <v4l2_fh_is_singular>`
2016-07-22 15:31:16 +03:00
(:c:type: `fh <v4l2_fh>` )
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
- Returns 1 if the file handle is the only open file handle, else 0.
2016-07-22 15:10:20 +03:00
2016-07-23 13:21:06 +03:00
:c:func: `v4l2_fh_is_singular_file <v4l2_fh_is_singular_file>`
2016-07-22 15:31:16 +03:00
(struct file \*filp)
2016-07-22 15:10:20 +03:00
2016-07-22 15:31:16 +03:00
- Same, but it calls v4l2_fh_is_singular with filp->private_data.
2016-07-22 15:10:20 +03:00
2016-07-22 16:15:42 +03:00
V4L2 fh functions and data structures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2016-07-22 15:06:45 +03:00
.. kernel-doc :: include/media/v4l2-fh.h