V4L2 file handles and event interface
Subsystems (2)
v5 cover V4L2 file handles and event interface
Hi,
Here's the seventh version of the V4L2 file handle and event interface patchset.
The patchset has been tested with the OMAP 3 ISP driver. Patches for OMAP 3 ISP are not part of this patchset but are available in Gitorious (branch is called event):
git://gitorious.org/omap3camera/mainline.git event
The patchset I'm posting now is against the v4l-dvb tree instead of linux-omap (ouch!). The omap3camera tree thus has a slightly different version of these patches.
Some more comments from Hans and Laurent. What has changed:
- Documentation for both file handles and events.
- Sequence number and event queue length patches have been combined with the events backend patch.
- Only VIDIOC_DQEVENT is now unconditionally handled by V4L2 without driver's involvement.
- __video_do_ioctl() checks that events have been initialised when handling event ioctls.
- There is a chance of being able to allocate a few more events to an event queue than intended. This is unlikely to be anyhow harmful, however.
- v4l2_event_subscribe_all() is now v4l2_event_subscribe_many().
- V4L2_FL_USES_V4L2_FH is set on video_device.flags in v4l2_fh_init() when the driver initialises the first file handle.
- Possibly something else I don't happen to remember just now.
Comments are welcome as always.
Cheers,
Signature · 2 lines
Sakari Ailus [email protected]
PATCH v5 1/6 V4L: File handles
This patch adds a list of v4l2_fh structures to every video_device. It allows using file handle related information in V4L2. The event interface is one example of such use.
Video device drivers should use the v4l2_fh pointer as their file->private_data.
--- drivers/media/video/Makefile | 2 +- drivers/media/video/v4l2-dev.c | 4 ++ drivers/media/video/v4l2-fh.c | 64 ++++++++++++++++++++++++++++++++++++++++ include/media/v4l2-dev.h | 5 +++ include/media/v4l2-fh.h | 42 ++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletions(-) create mode 100644 drivers/media/video/v4l2-fh.c create mode 100644 include/media/v4l2-fh.h
drivers/media/video/Makefile +1 -1
@@ -10,7 +10,7 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o -videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o +videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o # V4L2 core modules
drivers/media/video/v4l2-dev.c +4 -0
@@ -421,6 +421,10 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,if (!vdev->release)return -EINVAL ; +/* v4l2_fh support */ +spin_lock_init (&vdev->fh_lock); +INIT_LIST_HEAD (&vdev->fh_list); +/* Part 1: check device type */ switch (type) {case VFL_TYPE_GRABBER :
drivers/media/video/v4l2-fh.c new file +64 -0
64 lines not on this page · raw message
include/media/v4l2-dev.h +5 -0
@@ -32,6 +32,7 @@ struct v4l2_device;Drivers can clear this flag if they want to block all future device access. It is cleared by video_unregister_device. */ #define V4L2_FL_REGISTERED (0) +#define V4L2_FL_USES_V4L2_FH (1)struct v4l2_file_operations {struct module *owner;
@@ -77,6 +78,10 @@ struct video_device/* attribute to differentiate multiple indices on one physical device */ int index; +/* V4L2 file handles */ +spinlock_t fh_lock;/* Lock for all v4l2_fhs */ +struct list_head fh_list;/* List of struct v4l2_fh */ +int debug;/* Activates debug level*/ /* Video standard vars */
include/media/v4l2-fh.h new file +42 -0
42 lines not on this page · raw message
Signature · 1 line
1.5.6.5
RE: [PATCH v5 1/6] V4L: File handles
Heippa!
Quoted 65 lines
-----Original Message-----
From: [email protected] [mailto:linux-media- [email protected]] On Behalf Of Sakari Ailus
Sent: Friday, February 19, 2010 1:22 PM
To: [email protected]
Cc: [email protected]; [email protected]; iivanov@mm- sol.com; [email protected]; [email protected]; Sakari Ailus
Subject: [PATCH v5 1/6] V4L: File handlesThis patch adds a list of
v4l2_fhstructures to everyvideo_device. It allows using file handle related information in V4L2. The event interface
is one example of such use.Video device drivers should use the
v4l2_fhpointer as theirfile->private_data.Signed-off-by Sakari Ailus <[email protected]>--- drivers/media/video/Makefile | 2 +- drivers/media/video/v4l2-dev.c | 4 ++ drivers/media/video/v4l2-fh.c | 64 ++++++++++++++++++++++++++++++++++++++++ include/media/v4l2-dev.h | 5 +++ include/media/v4l2-fh.h | 42 ++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletions(-) create mode 100644 drivers/media/video/v4l2-fh.c create mode 100644 include/media/v4l2-fh.hdrivers/media/video/Makefile +1
-1@@ -10,7 +10,7 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o -videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o +videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o # V4L2 core modulesdrivers/media/video/v4l2- renamed from drivers/media/video/v4l2-dev.c +0
-0
dev.c
index 7090699..65a7b30 100644drivers/media/video/v4l2-dev.c +4
-0@@ -421,6 +421,10 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, if (!vdev->release) return -EINVAL; +/* v4l2_fh support */ +spin_lock_init (&vdev->fh_lock); +INIT_LIST_HEAD (&vdev->fh_list); +/* Part 1: check device type */ switch (type) {drivers/media/video/v4l2-dev.c +0
-0case VFL_TYPE_GRABBER :drivers/media/video/v4l2-fh.c new file +0
-0
drivers/media/video/v4l2-fh.c line 2
Quoted 2 lines
drivers/media/video/v4l2-fh.c new file +2
-0@@ -0,0 +1,64 @@ +/* +* drivers/media/video/v4l2-fh.c
[1] AFAIK, putting file paths is frowned upon.
Makes maintenance harder if in the future, this files get moved somewhere else.
drivers/media/video/v4l2-fh.c line 6
Quoted 4 lines
drivers/media/video/v4l2-fh.c new file +4
-0+* +* V4L2 file handles. +* +* Copyright (C) 2009 Nokia Corporation.
[2] Shouldn't it be "(C) 2010" already? :)
Quoted 88 lines
drivers/media/video/v4l2-fh.c new file +58
-0+* +* Contact: Sakari Ailus <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#include <linux/bitops.h> +#include <media/v4l2-dev.h> +#include <media/v4l2-fh.h> + +void v4l2_fh_init (struct v4l2_fh *fh,struct video_device *vdev) +{ + fh->vdev = vdev; +INIT_LIST_HEAD (&fh->list); +set_bit (V4L2_FL_USES_V4L2_FH , &fh->vdev->flags); +} +EXPORT_SYMBOL_GPL (v4l2_fh_init); + +void v4l2_fh_add (struct v4l2_fh *fh) +{ +unsigned long flags; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); +list_add (&fh->list, &fh->vdev->fh_list); +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +} +EXPORT_SYMBOL_GPL (v4l2_fh_add); + +void v4l2_fh_del (struct v4l2_fh *fh) +{ +unsigned long flags; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); +list_del_init (&fh->list); +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +} +EXPORT_SYMBOL_GPL (v4l2_fh_del); + +void v4l2_fh_exit (struct v4l2_fh *fh) +{ +if (fh->vdev ==NULL ) +return ; + + fh->vdev =NULL ; +} +EXPORT_SYMBOL_GPL (v4l2_fh_exit);include/media/v4l2-dev.h +1
-0@@ -32,6 +32,7 @@ struct v4l2_device;Drivers can clear this flag if they want to block all future device access. It is cleared by video_unregister_device. */ #define V4L2_FL_REGISTERED (0) +#define V4L2_FL_USES_V4L2_FH (1)struct v4l2_file_operations {struct module *owner;@@ -77,6 +78,10 @@ struct video_device/* attribute to differentiate multiple indices on one physical device */
include/media/v4l2-dev.h +4
-0int index; +/* V4L2 file handles */ +spinlock_t fh_lock;/* Lock for all v4l2_fhs */ +struct list_head fh_list;/* List of struct v4l2_fh */ +int debug;/* Activates debug level*/ /* Video standard vars */ include/media/v4l2-fh.h new file +0
-0
include/media/v4l2-fh.h line 2
Quoted 2 lines
include/media/v4l2-fh.h new file +2
-0@@ -0,0 +1,42 @@ +/* +* include/media/v4l2-fh.h
Same as [1]
include/media/v4l2-fh.h line 6
Quoted 4 lines
include/media/v4l2-fh.h new file +4
-0+* +* V4L2 file handle. +* +* Copyright (C) 2009 Nokia Corporation.
Same as [2]
Quoted 12 lines
include/media/v4l2-fh.h new file +12
-0+* +* Contact: Sakari Ailus <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +*
include/media/v4l2-fh.h line 28
Quoted 10 lines
include/media/v4l2-fh.h new file +10
-0+* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#ifndef V4L2_FH_H +#define V4L2_FH_H + +#include <linux/list.h>
Shouldn't you add one more header here?:
#include <media/v4l2-dev.h>
(for struct video_device)
Quoted 4 lines
include/media/v4l2-fh.h new file +4
-0+ +struct video_device ; + +struct v4l2_fh {
include/media/v4l2-fh.h line 42
Quoted 10 lines
include/media/v4l2-fh.h new file +10
-0+struct list_head list; + struct video_device *vdev; +}; + +void v4l2_fh_init (struct v4l2_fh *fh,struct video_device *vdev); +void v4l2_fh_add (struct v4l2_fh *fh); +void v4l2_fh_del (struct v4l2_fh *fh); +void v4l2_fh_exit (struct v4l2_fh *fh); + +#endif /* V4L2_EVENT_H */
Wrong comment, must have been:
/* V4L2_FH_H */
Regards,
Sergio
Quoted 7 lines
--
1.5.6.5--
To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 1/6] V4L: File handles
Hi Sergio,
Quoted 33 lines · Sergio
Heippa!
Quoted 31 lines
-----Original Message-----
From: [email protected] [mailto:linux-media- [email protected]] On Behalf Of Sakari Ailus
Sent: Friday, February 19, 2010 1:22 PM
To: [email protected]
Cc: [email protected]; [email protected]; iivanov@mm- sol.com; [email protected]; [email protected]; Sakari Ailus
Subject: [PATCH v5 1/6] V4L: File handlesThis patch adds a list of
v4l2_fhstructures to everyvideo_device. It allows using file handle related information in V4L2. The event interface
is one example of such use.Video device drivers should use the
v4l2_fhpointer as theirfile->private_data.Signed-off-by Sakari Ailus <[email protected]>---
drivers/media/video/Makefile | 2 +- drivers/media/video/v4l2-dev.c | 4 ++ drivers/media/video/v4l2-fh.c | 64++++++++++++++++++++++++++++++++++++++++
include/media/v4l2-dev.h | 5 +++ include/media/v4l2-fh.h | 42 ++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletions(-) create mode 100644 drivers/media/video/v4l2-fh.c create mode 100644 include/media/v4l2-fh.h
[snip]
Quoted 14 lines
drivers/media/video/v4l2-fh.c line 2
Quoted 8 lines
(quoted diff) +0
-0
b/drivers/media/video/v4l2-fh.cnew file mode 100644 index 0000000..c707930drivers/media/video/v4l2-fh.c new file +2
-0@@ -0,0 +1,64 @@ +/* +* drivers/media/video/v4l2-fh.c [1] AFAIK, putting file paths is frowned upon.
Makes maintenance harder if in the future, this files get moved somewhere else.
Quoted 6 lines
drivers/media/video/v4l2-fh.c line 6
Quoted 4 lines
drivers/media/video/v4l2-fh.c new file +4
-0+* +* V4L2 file handles. +* +* Copyright (C) 2009 Nokia Corporation. [2] Shouldn't it be "(C) 2010" already? :)
That shows how long the V4L2 events API review is taking ;-)
[snip]
Quoted 43 lines
include/media/v4l2-fh.h line 2
Quoted 8 lines
include/media/v4l2-fh.h new file +2
-0@@ -0,0 +1,42 @@ +/* +* include/media/v4l2-fh.h Same as [1]
include/media/v4l2-fh.h line 6
Quoted 4 lines
include/media/v4l2-fh.h new file +4
-0+* +* V4L2 file handle. +* +* Copyright (C) 2009 Nokia Corporation. Same as [2]
Quoted 12 lines
include/media/v4l2-fh.h new file +12
-0+* +* Contact: Sakari Ailus <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* include/media/v4l2-fh.h line 28
Quoted 10 lines
include/media/v4l2-fh.h new file +10
-0+* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#ifndef V4L2_FH_H +#define V4L2_FH_H + +#include <linux/list.h> Shouldn't you add one more header here?:
Quoted 3 lines
#include <
media/v4l2-dev.h>(for struct
video_device)
This header only needs struct video_device *, not struct video_device, so adding a forward definition will be more efficient (lower compilation time for compilation units that include v4l2-fh.h but not v4l2-dev.h).
Quoted 14 lines
Quoted 14 lines
include/media/v4l2-fh.h new file +14
-0+ +struct video_device ; + +struct v4l2_fh { +struct list_head list; +struct video_device *vdev; +}; + +void v4l2_fh_init (struct v4l2_fh *fh,struct video_device *vdev); +void v4l2_fh_add (struct v4l2_fh *fh); +void v4l2_fh_del (struct v4l2_fh *fh); +void v4l2_fh_exit (struct v4l2_fh *fh); + +#endif /* V4L2_EVENT_H */
Signature · 3 lines
Regards, Laurent Pinchart
RE: [PATCH v5 1/6] V4L: File handles
Laurent,
Quoted 63 lines
-----Original Message-----
From: Laurent Pinchart [mailto:[email protected]]
Sent: Friday, February 19, 2010 4:35 PM
To: Aguirre, Sergio
Cc: Sakari Ailus; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH v5 1/6] V4L: File handlesHi Sergio,
Quoted 9 lines · Sergio
Heippa!
Quoted 7 lines
-----Original Message-----
From: [email protected] [mailto:linux-media- [email protected]] On Behalf Of Sakari Ailus
Sent: Friday, February 19, 2010 1:22 PM
To: [email protected]
Cc: [email protected]; [email protected]; iivanov@mm- sol.com; [email protected]; [email protected]; SakariAilus
Quoted 24 lines
Quoted 24 lines
Subject: [PATCH v5 1/6] V4L: File handles
This patch adds a list of
v4l2_fhstructures to everyvideo_device. It allows using file handle related information in V4L2. The event interface
is one example of such use.Video device drivers should use the
v4l2_fhpointer as theirfile->private_data.Signed-off-by Sakari Ailus <[email protected]>---
drivers/media/video/Makefile | 2 +- drivers/media/video/v4l2-dev.c | 4 ++ drivers/media/video/v4l2-fh.c | 64++++++++++++++++++++++++++++++++++++++++
include/media/v4l2-dev.h | 5 +++ include/media/v4l2-fh.h | 42 ++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletions(-) create mode 100644 drivers/media/video/v4l2-fh.c create mode 100644 include/media/v4l2-fh.h[snip]
Quoted 11 lines
drivers/media/video/v4l2-fh.c line 2
Quoted 8 lines
(quoted diff) +0
-0
b/drivers/media/video/v4l2-fh.cnew file mode 100644 index 0000000..c707930drivers/media/video/v4l2-fh.c new file +2
-0@@ -0,0 +1,64 @@ +/* +* drivers/media/video/v4l2-fh.c [1] AFAIK, putting file paths is frowned upon.
Quoted 1 line
Makes maintenance harder if in the future, this files get moved
somewhere
Quoted 2 lines
else.
Quoted 8 lines
Quoted 6 lines
drivers/media/video/v4l2-fh.c line 6
Quoted 4 lines
drivers/media/video/v4l2-fh.c new file +4
-0+* +* V4L2 file handles. +* +* Copyright (C) 2009 Nokia Corporation. [2] Shouldn't it be "(C) 2010" already? :)
That shows how long the V4L2 events API review is taking ;-)
:D
Quoted 47 lines
[snip]
Quoted 11 lines
include/media/v4l2-fh.h line 2
Quoted 8 lines
include/media/v4l2-fh.h new file +2
-0@@ -0,0 +1,42 @@ +/* +* include/media/v4l2-fh.h Same as [1]
Quoted 15 lines
include/media/v4l2-fh.h line 6
Quoted 4 lines
include/media/v4l2-fh.h new file +4
-0+* +* V4L2 file handle. +* +* Copyright (C) 2009 Nokia Corporation. Same as [2]
Quoted 8 lines
include/media/v4l2-fh.h new file +8
-0+* +* Contact: Sakari Ailus <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but
Quoted 17 lines
Quoted 4 lines
include/media/v4l2-fh.h new file +4
-0+* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* include/media/v4l2-fh.h line 28
Quoted 10 lines
include/media/v4l2-fh.h new file +10
-0+* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#ifndef V4L2_FH_H +#define V4L2_FH_H + +#include <linux/list.h> Shouldn't you add one more header here?:
Quoted 8 lines
Quoted 3 lines
#include <
media/v4l2-dev.h>(for struct
video_device)This header only needs struct
video_device*, not structvideo_device, so adding a forward definition will be more efficient (lower compilation time for
compilation units that includev4l2-fh.hbut notv4l2-dev.h).
Ok, understood. Thanks for clarifying.
Regards,
Sergio
Quoted 20 lines
Quoted 15 lines
Quoted 5 lines
include/media/v4l2-fh.h new file +4
-0+ +struct video_device ; + +struct v4l2_fh {include/media/v4l2-fh.h line 42
Quoted 10 lines
include/media/v4l2-fh.h new file +10
-0+struct list_head list; + struct video_device *vdev; +}; + +void v4l2_fh_init (struct v4l2_fh *fh,struct video_device *vdev); +void v4l2_fh_add (struct v4l2_fh *fh); +void v4l2_fh_del (struct v4l2_fh *fh); +void v4l2_fh_exit (struct v4l2_fh *fh); + +#endif /* V4L2_EVENT_H */ --
Regards,Laurent Pinchart
Re: [PATCH v5 1/6] V4L: File handles
In reply to Aguirre, SergioQuoted 1 line · Sergio
Heippa!
Hi, Sergio!
Thanks for comments!
...
Quoted 7 lines
drivers/media/video/v4l2-fh.c line 2
Quoted 3 lines
drivers/media/video/v4l2-fh.c new file +2
-0@@ -0,0 +1,64 @@ +/* +* drivers/media/video/v4l2-fh.c [1] AFAIK, putting file paths is frowned upon.
Makes maintenance harder if in the future, this files get moved somewhere else.
Ack.
Quoted 6 lines
drivers/media/video/v4l2-fh.c line 6
Quoted 4 lines
drivers/media/video/v4l2-fh.c new file +4
-0+* +* V4L2 file handles. +* +* Copyright (C) 2009 Nokia Corporation. [2] Shouldn't it be "(C) 2010" already? :)
It is. The patches have been floating around since 2009 and I've just forgotten to update this. I hope no-one will notify 2010 must be replaced by 2011 at some point... ;-)
...
Quoted 5 lines
include/media/v4l2-fh.h line 42
Quoted 1 line
include/media/v4l2-fh.h new file +1
-0+#endif /* V4L2_EVENT_H */ Wrong comment, must have been:
/* V4L2_FH_H */
Will fix.
Signature · 2 lines
Sakari Ailus [email protected]
RE: [PATCH v5 1/6] V4L: File handles
Hi Sakari,
From: Sakari Ailus [mailto:[email protected]]
...
Quoted 1 line
Will fix.
Seems that you missed to fix this patch comments on your v6 version...
:-/
Regards,
Sergio
Quoted 4 lines
--
Sakari Ailus
[email protected]
Re: [PATCH v5 1/6] V4L: File handles
Quoted 11 lines · Sergio
Hi Sakari,
From: Sakari Ailus [mailto:[email protected]]
...
Quoted 1 line
Will fix.
Seems that you missed to fix this patch comments on your v6 version...
:-/
Um, true! I'll make the changes for the next one then.
Signature · 2 lines
Sakari Ailus [email protected]
PATCH v5 2/6 V4L: File handles: Add documentation
In reply to Sakari AilusAdd documentation on using V4L2 file handles (v4l2_fh) in V4L2 drivers.
--- Documentation/video4linux/v4l2-framework.txt | 36 ++++++++++++++++++++++++++ 1 files changed, 36 insertions(+), 0 deletions(-)
Documentation/video4linux/v4l2-framework.txt +36 -0
@@ -695,3 +695,39 @@ The better way to understand it is to take a look at vivi driver. One of the main reasons for vivi is to be a videobuf usage example. the vivi_thread_tick() does the task that the IRQ callback would do on PCI drivers (or the irq callback on USB). + +struct v4l2_fh +-------------- + +struct v4l2_fh provides a way to easily keep file handle specific data +that is used by the V4L2 framework. + +struct v4l2_fh is allocated as a part of the driver's own file handle +structure and is set to file->private_data in the driver's open +function by the driver. Drivers can extract their own file handle +structure by using the container_of macro. + +Useful functions: + +- v4l2_fh_init() + + Initialise the file handle. + +- v4l2_fh_add() + + Add a v4l2_fh to video_device file handle list. May be called after + initialising the file handle. + +- v4l2_fh_del() + + Unassociate the file handle from video_device(). The file handle + exit function may now be called. + +- v4l2_fh_exit() + + Uninitialise the file handle. After uninitialisation the v4l2_fh + memory can be freed. + +The users of v4l2_fh know whether a driver uses v4l2_fh as its +file.private_data pointer by testing the V4L2_FL_USES_V4L2_FH bit in +video_device.flags.
Signature · 1 line
1.5.6.5
Re: [PATCH v5 2/6] V4L: File handles: Add documentation
Quoted 41 lines · On Friday 19 February 2010 20:21:56 Sakari Ailus wrote:
Add documentation on using V4L2 file handles (
v4l2_fh) in V4L2 drivers.Signed-off-by Sakari Ailus <[email protected]>--- Documentation/video4linux/v4l2-framework.txt | 36 ++++++++++++++++++++++++++ 1 files changed, 36 insertions(+), 0 deletions(-)Documentation/video4linux/v4l2-framework.txt +26
-0@@ -695,3 +695,39 @@ The better way to understand it is to take a look at vivi driver. One of the main reasons for vivi is to be a videobuf usage example. the vivi_thread_tick() does the task that the IRQ callback would do on PCI drivers (or the irq callback on USB). + +struct v4l2_fh +-------------- + +struct v4l2_fh provides a way to easily keep file handle specific data +that is used by the V4L2 framework. + +struct v4l2_fh is allocated as a part of the driver's own file handle +structure and is set to file->private_data in the driver's open +function by the driver. Drivers can extract their own file handle +structure by using the container_of macro. + +Useful functions: + +- v4l2_fh_init() + + Initialise the file handle. + +- v4l2_fh_add() + + Add a v4l2_fh to video_device file handle list. May be called after + initialising the file handle. + +- v4l2_fh_del() + + Unassociate the file handle from video_device(). The file handle
Documentation/video4linux/v4l2-framework.txt The better way to understand it is to take a look at vivi driver. One · line 733
Quoted 10 lines
Documentation/video4linux/v4l2-framework.txt +10
-0+ exit function may now be called. + +- v4l2_fh_exit() + + Uninitialise the file handle. After uninitialisation the v4l2_fh + memory can be freed. + +The users of v4l2_fh know whether a driver uses v4l2_fh as its +file.private_data pointer by testing the V4L2_FL_USES_V4L2_FH bit in +video_device.flags.
Replace '.' by '->':
file->private_datavideo_device->flags
Quoted 1 line
Signature · 1 line
Hans Verkuil - video4linux developer - sponsored by TANDBERG
PATCH v5 3/6 V4L: Events: Add new ioctls for events
In reply to Sakari AilusThis patch adds a set of new ioctls to the V4L2 API. The ioctls conform to V4L2 Events RFC version 2.3:
<URL:http://www.spinics.net/lists/linux-media/msg12033.html>
--- drivers/media/video/v4l2-compat-ioctl32.c | 3 +++ drivers/media/video/v4l2-ioctl.c | 3 +++ include/linux/videodev2.h | 26 ++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 0 deletions(-)
drivers/media/video/v4l2-compat-ioctl32.c +3 -0
@@ -1086,6 +1086,9 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)case VIDIOC_QUERY_DV_PRESET :case VIDIOC_S_DV_TIMINGS :case VIDIOC_G_DV_TIMINGS : +case VIDIOC_DQEVENT : +case VIDIOC_SUBSCRIBE_EVENT : +case VIDIOC_UNSUBSCRIBE_EVENT : ret =do_video_ioctl (file, cmd, arg);break ;
drivers/media/video/v4l2-ioctl.c +3 -0
@@ -290,6 +290,9 @@ static const char *v4l2_ioctls[] = { [_IOC_NR(VIDIOC_QUERY_DV_PRESET)] = "VIDIOC_QUERY_DV_PRESET", [_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS", [_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS", + [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT", + [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT", + [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT", };#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
include/linux/videodev2.h +26 -0
@@ -1622,6 +1622,29 @@ struct v4l2_streamparm { };/* +* E V E N T S +*/ + +struct v4l2_event { +__u32 type; +union { +__u8 data[64 ]; + } u; +__u32 pending; +__u32 sequence; +struct timespec timestamp; +__u32 reserved[9 ]; +}; + +struct v4l2_event_subscription { +__u32 type; +__u32 reserved[7 ]; +}; + +#define V4L2_EVENT_ALL 0 +#define V4L2_EVENT_PRIVATE_START 0x08000000 + +/* * A D V A N C E D D E B U G G I N G * * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS!
@@ -1743,6 +1766,9 @@ struct v4l2_dbg_chip_ident {#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset)#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings)#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) +#define VIDIOC_DQEVENT _IOR('V', 83, struct v4l2_event) +#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 84, struct v4l2_event_subscription) +#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 85, struct v4l2_event_subscription)/* Reminder: when adding new ioctls please add support for them to drivers/media/video/v4l2-compat-ioctl32.c as well! */
Signature · 1 line
1.5.6.5
PATCH v5 4/6 V4L: Events: Add backend
In reply to Sakari AilusAdd event handling backend to V4L2. The backend handles event subscription and delivery to file handles. Event subscriptions are based on file handle. Events may be delivered to all subscribed file handles on a device independent of where they originate from.
--- drivers/media/video/Makefile | 3 +- drivers/media/video/v4l2-event.c | 286 ++++++++++++++++++++++++++++++++++++++ drivers/media/video/v4l2-fh.c | 4 + include/media/v4l2-event.h | 65 +++++++++ include/media/v4l2-fh.h | 2 + 5 files changed, 359 insertions(+), 1 deletions(-) create mode 100644 drivers/media/video/v4l2-event.c create mode 100644 include/media/v4l2-event.h
drivers/media/video/Makefile +2 -1
@@ -10,7 +10,8 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o -videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o +videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ + v4l2-event.o # V4L2 core modules
drivers/media/video/v4l2-event.c new file +286 -0
286 lines not on this page · raw message
drivers/media/video/v4l2-fh.c +4 -0
@@ -25,11 +25,13 @@#include <linux/bitops.h> #include <media/v4l2-dev.h> #include <media/v4l2-fh.h> +#include <media/v4l2-event.h> void v4l2_fh_init (struct v4l2_fh *fh,struct video_device *vdev) { fh->vdev = vdev;INIT_LIST_HEAD (&fh->list); + fh->events =NULL ;set_bit (V4L2_FL_USES_V4L2_FH , &fh->vdev->flags); }EXPORT_SYMBOL_GPL (v4l2_fh_init);
@@ -60,5 +62,7 @@ void v4l2_fh_exit(struct v4l2_fh *fh)return ; fh->vdev =NULL ; + +v4l2_event_free (fh); }EXPORT_SYMBOL_GPL (v4l2_fh_exit);
include/media/v4l2-event.h new file +65 -0
65 lines not on this page · raw message
include/media/v4l2-fh.h +2 -0
@@ -28,10 +28,12 @@#include <linux/list.h> struct video_device ; +struct v4l2_events ;struct v4l2_fh {struct list_head list;struct video_device *vdev; +struct v4l2_events *events;/* events, pending and subscribed */ };void v4l2_fh_init (struct v4l2_fh *fh,struct video_device *vdev);
Signature · 1 line
1.5.6.5
RE: [PATCH v5 4/6] V4L: Events: Add backend
Heippa!
Quoted 48 lines
-----Original Message-----
From: [email protected] [mailto:linux-media- [email protected]] On Behalf Of Sakari Ailus
Sent: Friday, February 19, 2010 1:22 PM
To: [email protected]
Cc: [email protected]; [email protected]; iivanov@mm- sol.com; [email protected]; [email protected]; Sakari Ailus
Subject: [PATCH v5 4/6] V4L: Events: Add backendAdd event handling backend to V4L2. The backend handles event subscription and delivery to file handles. Event subscriptions are based on file handle.
Events may be delivered to all subscribed file handles on a device independent of where they originate from.Signed-off-by Sakari Ailus <[email protected]>--- drivers/media/video/Makefile | 3 +- drivers/media/video/v4l2-event.c | 286 ++++++++++++++++++++++++++++++++++++++ drivers/media/video/v4l2-fh.c | 4 + include/media/v4l2-event.h | 65 +++++++++ include/media/v4l2-fh.h | 2 + 5 files changed, 359 insertions(+), 1 deletions(-) create mode 100644 drivers/media/video/v4l2-event.c create mode 100644 include/media/v4l2-event.hdrivers/media/video/Makefile +2
-1@@ -10,7 +10,8 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o -videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o +videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ + v4l2-event.o # V4L2 core modulesdrivers/media/video/v4l2- renamed from drivers/media/video/v4l2-event.c +0
-0
event.c
new file mode 100644
index 0000000..ab31cc6
drivers/media/video/v4l2-event.c line 2
Quoted 2 lines
drivers/media/video/v4l2-event.c new file +2
-0@@ -0,0 +1,286 @@ +/* +* drivers/media/video/v4l2-event.c
No filepaths.
drivers/media/video/v4l2-event.c line 6
Quoted 4 lines
drivers/media/video/v4l2-event.c new file +4
-0+* +* V4L2 events. +* +* Copyright (C) 2009 Nokia Corporation.
2010
Quoted 100 lines
drivers/media/video/v4l2-event.c new file +100
-0+* +* Contact: Sakari Ailus <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#include <media/v4l2-dev.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> + +#include <linux/sched.h> + +static int v4l2_event_init (struct v4l2_fh *fh) +{ + fh->events =kzalloc (sizeof (*fh->events),GFP_KERNEL ); +if (fh->events ==NULL ) +return -ENOMEM ; + +init_waitqueue_head (&fh->events->wait); + +INIT_LIST_HEAD (&fh->events->free); +INIT_LIST_HEAD (&fh->events->available); +INIT_LIST_HEAD (&fh->events->subscribed); + + fh->events->sequence =-1 ; + +return 0 ; +} + +int v4l2_event_alloc (struct v4l2_fh *fh,unsigned int n) +{ +struct v4l2_events *events; +unsigned long flags; +int ret; + +if (!fh->events) { + ret =v4l2_event_init (fh); +if (ret) +return ret; + } + + events = fh->events; + +while (events->nallocated < n) { +struct v4l2_kevent *kev; + + kev =kzalloc (sizeof (*kev),GFP_KERNEL ); +if (kev ==NULL ) +return -ENOMEM ; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); +list_add_tail (&kev->list, &events->free); + events->nallocated++; +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); + } + +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_alloc); + +#define list_kfree (list, type, member) \ + while (!list_empty(list)) { \ + type *hi; \ + hi = list_first_entry(list, type, member); \ + list_del(&hi->member); \ + kfree(hi); \ + } + +void v4l2_event_free (struct v4l2_fh *fh) +{ +struct v4l2_events *events = fh->events; + +if (!events) +return ; + + list_kfree(&events->free, struct v4l2_kevent, list); + list_kfree(&events->available, struct v4l2_kevent, list); + list_kfree(&events->subscribed, struct v4l2_subscribed_event, list); + +kfree (events); + fh->events =NULL ; +} +EXPORT_SYMBOL_GPL (v4l2_event_free); + +int v4l2_event_dequeue (struct v4l2_fh *fh,struct v4l2_event *event) +{ +struct v4l2_events *events = fh->events; +struct v4l2_kevent *kev;
drivers/media/video/v4l2-event.c line 116
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+unsigned long flags; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + +if (list_empty (&events->available)) { +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +return -ENOENT ; + } + +WARN_ON (events->navailable ==0 );
I don't think the above warning will ever happen. Looks a bit over protective to me.
Whenever you update your "events->available" list, you're holding the fh_lock spinlock, so there's no chance that the list of events would contan a different number of elents to what the navailable var is holding. Is it?
Please correct me if I'm missing something...
Or if you insist in checking, you could just have done this instead:
if (list_empty(&events->available) || (events->navailable == 0)) {
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
return -ENOENT;
}As it doesn't make sense to proceed if navailable is zero, I believe...
Quoted 205 lines
drivers/media/video/v4l2-event.c new file +2
-0+ + kev = list_first_entry(&events->available, struct v4l2_kevent,list);
drivers/media/video/v4l2-event.c new file +27
-0+list_move (&kev->list, &events->free); + events->navailable--; + + kev->event.pending = events->navailable; + *event = kev->event; + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); + +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_dequeue); + +static struct v4l2_subscribed_event *v4l2_event_subscribed ( +struct v4l2_fh *fh,u32 type) +{ +struct v4l2_events *events = fh->events; +struct v4l2_subscribed_event *sev; + +list_for_each_entry (sev, &events->subscribed, list) { +if (sev->type == type) +return sev; + } + +return NULL ; +} + +void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event*ev)
drivers/media/video/v4l2-event.c new file +28
-0+{ +struct v4l2_fh *fh; +unsigned long flags; +struct timespec timestamp; + +ktime_get_ts (×tamp); + +spin_lock_irqsave (&vdev->fh_lock, flags); + +list_for_each_entry (fh, &vdev->fh_list, list) { +struct v4l2_events *events = fh->events; +struct v4l2_kevent *kev; +u32 sequence; + +/* Are we subscribed? */ +if (!v4l2_event_subscribed (fh, ev->type)) +continue ; + +/* Increase event sequence number on fh. */ + events->sequence++; + sequence = events->sequence; + +/* Do we have any free events? */ +if (list_empty (&events->free)) +continue ; + +/* Take one and fill it. */ + kev = list_first_entry(&events->free, struct v4l2_kevent,list);
drivers/media/video/v4l2-event.c new file +113
-0+ kev->event.type = ev->type; + kev->event.u = ev->u; + kev->event.timestamp = timestamp; + kev->event.sequence = sequence; +list_move_tail (&kev->list, &events->available); + + events->navailable++; + +wake_up_all (&events->wait); + } + +spin_unlock_irqrestore (&vdev->fh_lock, flags); +} +EXPORT_SYMBOL_GPL (v4l2_event_queue); + +int v4l2_event_pending (struct v4l2_fh *fh) +{ +return fh->events->navailable; +} +EXPORT_SYMBOL_GPL (v4l2_event_pending); + +int v4l2_event_subscribe (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub) +{ +struct v4l2_events *events = fh->events; +struct v4l2_subscribed_event *sev; +unsigned long flags; + + sev =kmalloc (sizeof (*sev),GFP_KERNEL ); +if (!sev) +return -ENOMEM ; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + +if (v4l2_event_subscribed (fh, sub->type) ==NULL ) { +INIT_LIST_HEAD (&sev->list); + sev->type = sub->type; + +list_add (&sev->list, &events->subscribed); + } + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); + +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_subscribe); + +/* subscribe a zero-terminated array of events */ +int v4l2_event_subscribe_many (struct v4l2_fh *fh,const u32 *all) +{ +int ret; + +for (; *all; all++) { +struct v4l2_event_subscription sub; + + sub.type = *all; + + ret =v4l2_event_subscribe (fh, &sub); +if (ret) +return ret; + } + +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_subscribe_many); + +static void v4l2_event_unsubscribe_all (struct v4l2_fh *fh) +{ +struct v4l2_events *events = fh->events; +unsigned long flags; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + +while (!list_empty (&events->subscribed)) { +struct v4l2_subscribed_event *sev; + + sev =list_first_entry (&events->subscribed, + struct v4l2_subscribed_event, list); + +list_del (&sev->list); +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +kfree (sev); +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + } + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +} + +int v4l2_event_unsubscribe (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub) +{ +struct v4l2_subscribed_event *sev; +unsigned long flags; + +if (sub->type ==V4L2_EVENT_ALL ) { +v4l2_event_unsubscribe_all (fh); +return 0 ; + } + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + + sev =v4l2_event_subscribed (fh, sub->type); +if (sev !=NULL ) +list_del (&sev->list); + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); + +if (sev !=NULL ) +kfree (sev); + +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_unsubscribe);drivers/media/video/v4l2-fh.c +4
-0@@ -25,11 +25,13 @@#include <linux/bitops.h> #include <media/v4l2-dev.h> #include <media/v4l2-fh.h> +#include <media/v4l2-event.h> void v4l2_fh_init (struct v4l2_fh *fh,struct video_device *vdev) { fh->vdev = vdev;INIT_LIST_HEAD (&fh->list); + fh->events =NULL ;set_bit (V4L2_FL_USES_V4L2_FH , &fh->vdev->flags); }EXPORT_SYMBOL_GPL (v4l2_fh_init);@@ -60,5 +62,7 @@ void v4l2_fh_exit(struct v4l2_fh *fh)return ; fh->vdev =NULL ; + +v4l2_event_free (fh); }EXPORT_SYMBOL_GPL (v4l2_fh_exit);include/media/v4l2-event.h new file +0
-0
include/media/v4l2-event.h line 2
Quoted 2 lines
include/media/v4l2-event.h new file +2
-0@@ -0,0 +1,65 @@ +/* +* include/media/v4l2-event.h
Again, no filepaths.
include/media/v4l2-event.h line 6
Quoted 4 lines
include/media/v4l2-event.h new file +4
-0+* +* V4L2 events. +* +* Copyright (C) 2009 Nokia Corporation.
2010
Regards,
Sergio
Quoted 85 lines
include/media/v4l2-event.h new file +51
-0+* +* Contact: Sakari Ailus <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#ifndef V4L2_EVENT_H +#define V4L2_EVENT_H + +#include <linux/types.h> +#include <linux/videodev2.h> + +struct v4l2_fh ; +struct video_device ; + +struct v4l2_kevent { +struct list_head list; +struct v4l2_event event; +}; + +struct v4l2_subscribed_event { +struct list_head list; +u32 type; +}; + +struct v4l2_events { +wait_queue_head_t wait; +struct list_head subscribed;/* Subscribed events */ +struct list_head available;/* Dequeueable event */ +unsigned int navailable; +struct list_head free;/* Events ready for use */ +unsigned int nallocated;/* Number of allocated events */ +u32 sequence; +}; + +int v4l2_event_alloc (struct v4l2_fh *fh,unsigned int n); +void v4l2_event_free (struct v4l2_fh *fh); +int v4l2_event_dequeue (struct v4l2_fh *fh,struct v4l2_event *event); +void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event*ev);
include/media/v4l2-event.h new file +8
-0+int v4l2_event_pending (struct v4l2_fh *fh); +int v4l2_event_subscribe (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub); +int v4l2_event_subscribe_many (struct v4l2_fh *fh,const u32 *all); +int v4l2_event_unsubscribe (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub); + +#endif /* V4L2_EVENT_H */ include/media/v4l2-fh.h +2
-0@@ -28,10 +28,12 @@#include <linux/list.h> struct video_device ; +struct v4l2_events ;struct v4l2_fh {struct list_head list;struct video_device *vdev; +struct v4l2_events *events;/* events, pending and subscribed */ };void
v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev);
--
1.5.6.5--
To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 4/6] V4L: Events: Add backend
Quoted 1 line · Sergio
Heippa!
Hi, Sergio!
Your lines seem to be over 80 characters long. :I
...
Quoted 8 lines
Quoted 8 lines
drivers/media/video/v4l2-event.c new file +8
-0+int v4l2_event_dequeue (struct v4l2_fh *fh,struct v4l2_event *event) +{ +struct v4l2_events *events = fh->events; +struct v4l2_kevent *kev; +unsigned long flags; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); +
Quoted 8 lines
drivers/media/video/v4l2-event.c line 116
Quoted 6 lines
drivers/media/video/v4l2-event.c new file +6
-0+if (list_empty (&events->available)) { +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +return -ENOENT ; + } + +WARN_ON (events->navailable ==0 );I don't think the above warning will ever happen. Looks a bit over protective to me.
If it does it's a bug somewhere.
Quoted 3 lines
Whenever you update your "
events->available" list, you're holding thefh_lockspinlock, so there's no chance that the list of events would contan a different number of elents to what the navailable var is holding. Is it?Please correct me if I'm missing something...
At the moment that is true as far as I see it. But if it's changed in future chances are something goes wrong. It's a simple check but might save some headaches.
Quoted 8 lines
Or if you insist in checking, you could just have done this instead:
if (list_empty(&events->available) || (events->navailable == 0)) { spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); return -ENOENT; }As it doesn't make sense to proceed if navailable is zero, I believe...
It'd be a bug in the code so it must be WARN_ON().
I think the question is whether the check should be left there or removed.
Signature · 2 lines
Sakari Ailus [email protected]
Re: [PATCH v5 4/6] V4L: Events: Add backend
In reply to Sakari AilusHi Sakari,
Here are some more comments.
Quoted 158 lines · On Friday 19 February 2010 20:21:58 Sakari Ailus wrote:
Add event handling backend to V4L2. The backend handles event subscription and delivery to file handles. Event subscriptions are based on file handle. Events may be delivered to all subscribed file handles on a device independent of where they originate from.
Signed-off-by Sakari Ailus <[email protected]>--- drivers/media/video/Makefile | 3 +- drivers/media/video/v4l2-event.c | 286 ++++++++++++++++++++++++++++++++++++++ drivers/media/video/v4l2-fh.c | 4 + include/media/v4l2-event.h | 65 +++++++++ include/media/v4l2-fh.h | 2 + 5 files changed, 359 insertions(+), 1 deletions(-) create mode 100644 drivers/media/video/v4l2-event.c create mode 100644 include/media/v4l2-event.hdrivers/media/video/Makefile +2
-1@@ -10,7 +10,8 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o -videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o +videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ + v4l2-event.o # V4L2 core modulesdrivers/media/video/v4l2-event.c new file +122
-0@@ -0,0 +1,286 @@ +/* +* drivers/media/video/v4l2-event.c +* +* V4L2 events. +* +* Copyright (C) 2009 Nokia Corporation. +* +* Contact: Sakari Ailus <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#include <media/v4l2-dev.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> + +#include <linux/sched.h> + +static int v4l2_event_init (struct v4l2_fh *fh) +{ + fh->events =kzalloc (sizeof (*fh->events),GFP_KERNEL ); +if (fh->events ==NULL ) +return -ENOMEM ; + +init_waitqueue_head (&fh->events->wait); + +INIT_LIST_HEAD (&fh->events->free); +INIT_LIST_HEAD (&fh->events->available); +INIT_LIST_HEAD (&fh->events->subscribed); + + fh->events->sequence =-1 ; + +return 0 ; +} + +int v4l2_event_alloc (struct v4l2_fh *fh,unsigned int n) +{ +struct v4l2_events *events; +unsigned long flags; +int ret; + +if (!fh->events) { + ret =v4l2_event_init (fh); +if (ret) +return ret; + } + + events = fh->events; + +while (events->nallocated < n) { +struct v4l2_kevent *kev; + + kev =kzalloc (sizeof (*kev),GFP_KERNEL ); +if (kev ==NULL ) +return -ENOMEM ; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); +list_add_tail (&kev->list, &events->free); + events->nallocated++; +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); + } + +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_alloc); + +#define list_kfree (list, type, member) \ + while (!list_empty(list)) { \ + type *hi; \ + hi = list_first_entry(list, type, member); \ + list_del(&hi->member); \ + kfree(hi); \ + } + +void v4l2_event_free (struct v4l2_fh *fh) +{ +struct v4l2_events *events = fh->events; + +if (!events) +return ; + + list_kfree(&events->free, struct v4l2_kevent, list); + list_kfree(&events->available, struct v4l2_kevent, list); + list_kfree(&events->subscribed, struct v4l2_subscribed_event, list); + +kfree (events); + fh->events =NULL ; +} +EXPORT_SYMBOL_GPL (v4l2_event_free); + +int v4l2_event_dequeue (struct v4l2_fh *fh,struct v4l2_event *event) +{ +struct v4l2_events *events = fh->events; +struct v4l2_kevent *kev; +unsigned long flags; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + +if (list_empty (&events->available)) { +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +return -ENOENT ; + } + +WARN_ON (events->navailable ==0 ); + + kev = list_first_entry(&events->available, struct v4l2_kevent, list); +list_move (&kev->list, &events->free); + events->navailable--; + + kev->event.pending = events->navailable;
drivers/media/video/v4l2-event.c line 132
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+ *event = kev->event; + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); + +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_dequeue); + +static struct v4l2_subscribed_event *v4l2_event_subscribed ( +struct v4l2_fh *fh,u32 type)
Add a comment before this function that mentions that fh->vdev->fh_lock must be held before calling this.
Quoted 24 lines
drivers/media/video/v4l2-event.c new file +24
-0+{ +struct v4l2_events *events = fh->events; +struct v4l2_subscribed_event *sev; + +list_for_each_entry (sev, &events->subscribed, list) { +if (sev->type == type) +return sev; + } + +return NULL ; +} + +void v4l2_event_queue (struct video_device *vdev,const struct v4l2_event *ev) +{ +struct v4l2_fh *fh; +unsigned long flags; +struct timespec timestamp; + +ktime_get_ts (×tamp); + +spin_lock_irqsave (&vdev->fh_lock, flags); + +list_for_each_entry (fh, &vdev->fh_list, list) { +struct v4l2_events *events = fh->events;
drivers/media/video/v4l2-event.c line 166
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+struct v4l2_kevent *kev; +u32 sequence; + +/* Are we subscribed? */ +if (!v4l2_event_subscribed (fh, ev->type)) +continue ; + +/* Increase event sequence number on fh. */ + events->sequence++; + sequence = events->sequence;
There is no need for a temp sequence variable...
drivers/media/video/v4l2-event.c line 177
Quoted 11 lines
drivers/media/video/v4l2-event.c new file +11
-0+ +/* Do we have any free events? */ +if (list_empty (&events->free)) +continue ; + +/* Take one and fill it. */ + kev = list_first_entry(&events->free, struct v4l2_kevent, list); + kev->event.type = ev->type; + kev->event.u = ev->u; + kev->event.timestamp = timestamp; + kev->event.sequence = sequence;
... you can just use events->sequence directly here.
Quoted 14 lines
drivers/media/video/v4l2-event.c new file +14
-0+list_move_tail (&kev->list, &events->available); + + events->navailable++; + +wake_up_all (&events->wait); + } + +spin_unlock_irqrestore (&vdev->fh_lock, flags); +} +EXPORT_SYMBOL_GPL (v4l2_event_queue); + +int v4l2_event_pending (struct v4l2_fh *fh) +{ +return fh->events->navailable;
drivers/media/video/v4l2-event.c line 201
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+} +EXPORT_SYMBOL_GPL (v4l2_event_pending); + +int v4l2_event_subscribe (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub) +{ +struct v4l2_events *events = fh->events; +struct v4l2_subscribed_event *sev; +unsigned long flags; +
Add this:
if (events == NULL) {
/* If we get here, then the driver forgot to allocate events. */
WARN_ON(1);
return -ENOMEM;
}If subscribe is called without the event queue being allocated, then the driver did something wrong.
See also my review for patch 5/6.
Quoted 4 lines
drivers/media/video/v4l2-event.c new file +4
-0+ sev =kmalloc (sizeof (*sev),GFP_KERNEL ); +if (!sev) +return -ENOMEM ; +
drivers/media/video/v4l2-event.c line 215
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+spin_lock_irqsave (&fh->vdev->fh_lock, flags); + +if (v4l2_event_subscribed (fh, sub->type) ==NULL ) { +INIT_LIST_HEAD (&sev->list); + sev->type = sub->type; + +list_add (&sev->list, &events->subscribed); + } + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags);
If the event was already subscribed, then you need to kfree the earlier allocated sev here. Otherwise you have a memory leak.
Quoted 13 lines
drivers/media/video/v4l2-event.c new file +13
-0+ +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_subscribe); + +/* subscribe a zero-terminated array of events */ +int v4l2_event_subscribe_many (struct v4l2_fh *fh,const u32 *all) +{ +int ret; + +for (; *all; all++) { +struct v4l2_event_subscription sub; +
drivers/media/video/v4l2-event.c line 238
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+ sub.type = *all; + + ret =v4l2_event_subscribe (fh, &sub); +if (ret) +return ret; + } + +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_subscribe_many);
Supporting V4L2_EVENT_ALL is a bad idea when subscribing. It sounds nice initially, but the longer I think about it the more convinced I am we should not do this. The main argument is really that it can lead to unexpected behavior. Suppose a userspace application subscribes to all events. And in a later version of the driver new events are added. Suddenly those will also arrive in the userspace app.
This might cause it to crash if it was written badly and it didn't check against unknown events. Or this new event might be a high-volume event which might flood the application unexpectedly.
In other words, it can create uncertain future behavior. So we really should support EVENT_ALL only for unsubscribe: there it is very useful as a simple way to 'reset' the filehandle's event handling.
Quoted 12 lines
drivers/media/video/v4l2-event.c new file +12
-0+ +static void v4l2_event_unsubscribe_all (struct v4l2_fh *fh) +{ +struct v4l2_events *events = fh->events; +unsigned long flags; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + +while (!list_empty (&events->subscribed)) { +struct v4l2_subscribed_event *sev; + + sev = list_first_entry(&events->subscribed,
drivers/media/video/v4l2-event.c line 260
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+ struct v4l2_subscribed_event, list); + +list_del (&sev->list); +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +kfree (sev); +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + } + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +}
What about this:
static void v4l2_event_unsubscribe_all(struct v4l2_fh *fh)
{
struct v4l2_events *events = fh->events;
struct v4l2_subscribed_event *sev;
unsigned long flags;
do {
sev = NULL;
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
if (!list_empty(&events->subscribed)) {
sev = list_first_entry(&events->subscribed,
struct v4l2_subscribed_event, list);
list_del(&sev->list);
}
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
kfree(sev);
} while (sev);
}This avoids the 'interleaved' locking which I never like.
Quoted 12 lines
drivers/media/video/v4l2-event.c new file +12
-0+ +int v4l2_event_unsubscribe (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub) +{ +struct v4l2_subscribed_event *sev; +unsigned long flags; + +if (sub->type ==V4L2_EVENT_ALL ) { +v4l2_event_unsubscribe_all (fh); +return 0 ; + } +
drivers/media/video/v4l2-event.c line 282
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+spin_lock_irqsave (&fh->vdev->fh_lock, flags); + + sev =v4l2_event_subscribed (fh, sub->type); +if (sev !=NULL ) +list_del (&sev->list); + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); + +if (sev !=NULL ) +kfree (sev);
No need for the NULL check. kfree(NULL) is allowed.
Quoted 75 lines
drivers/media/video/v4l2-event.c new file +4
-0+ +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_unsubscribe);drivers/media/video/v4l2-fh.c +4
-0@@ -25,11 +25,13 @@#include <linux/bitops.h> #include <media/v4l2-dev.h> #include <media/v4l2-fh.h> +#include <media/v4l2-event.h> void v4l2_fh_init (struct v4l2_fh *fh,struct video_device *vdev) { fh->vdev = vdev;INIT_LIST_HEAD (&fh->list); + fh->events =NULL ;set_bit (V4L2_FL_USES_V4L2_FH , &fh->vdev->flags); }EXPORT_SYMBOL_GPL (v4l2_fh_init);@@ -60,5 +62,7 @@ void v4l2_fh_exit(struct v4l2_fh *fh)return ; fh->vdev =NULL ; + +v4l2_event_free (fh); }EXPORT_SYMBOL_GPL (v4l2_fh_exit);include/media/v4l2-event.h new file +39
-0@@ -0,0 +1,65 @@ +/* +* include/media/v4l2-event.h +* +* V4L2 events. +* +* Copyright (C) 2009 Nokia Corporation. +* +* Contact: Sakari Ailus <[email protected]> +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +*/ + +#ifndef V4L2_EVENT_H +#define V4L2_EVENT_H + +#include <linux/types.h> +#include <linux/videodev2.h> + +struct v4l2_fh ; +struct video_device ; + +struct v4l2_kevent { +struct list_head list; +struct v4l2_event event; +}; + +struct v4l2_subscribed_event {
include/media/v4l2-event.h line 49
Quoted 10 lines
include/media/v4l2-event.h new file +10
-0+struct list_head list; +u32 type; +}; + +struct v4l2_events { +wait_queue_head_t wait; +struct list_head subscribed;/* Subscribed events */ +struct list_head available;/* Dequeueable event */ +unsigned int navailable; +struct list_head free;/* Events ready for use */
I would move this between the subscribed and available lists. Purely for grouping the lists together.
Quoted 24 lines
include/media/v4l2-event.h new file +16
-0+unsigned int nallocated;/* Number of allocated events */ + u32 sequence; +}; + +int v4l2_event_alloc (struct v4l2_fh *fh,unsigned int n); +void v4l2_event_free (struct v4l2_fh *fh); +int v4l2_event_dequeue (struct v4l2_fh *fh,struct v4l2_event *event); +void v4l2_event_queue (struct video_device *vdev,const struct v4l2_event *ev); +int v4l2_event_pending (struct v4l2_fh *fh); +int v4l2_event_subscribe (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub); +int v4l2_event_subscribe_many (struct v4l2_fh *fh,const u32 *all); +int v4l2_event_unsubscribe (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub); + +#endif /* V4L2_EVENT_H */ include/media/v4l2-fh.h +0
-0@@ -28,10 +28,12 @@#include <linux/list.h>
include/media/v4l2-fh.h line 39
Quoted 10 lines
include/media/v4l2-fh.h +2
-0struct video_device ; +struct v4l2_events ;struct v4l2_fh {struct list_head list;struct video_device *vdev; +struct v4l2_events *events;/* events, pending and subscribed */ };void v4l2_fh_init (struct v4l2_fh *fh,struct video_device *vdev);
Regards,
Hans
Signature · 1 line
Hans Verkuil - video4linux developer - sponsored by TANDBERG
Re: [PATCH v5 4/6] V4L: Events: Add backend
Quoted 1 line · Hans Verkuil
Hi Sakari,
Hi Hans,
And many thanks for the comments again!
Quoted 2 lines
Here are some more comments.
...
Quoted 25 lines
Quoted 25 lines
drivers/media/video/v4l2-event.c new file +25
-0+int v4l2_event_dequeue (struct v4l2_fh *fh,struct v4l2_event *event) +{ +struct v4l2_events *events = fh->events; +struct v4l2_kevent *kev; +unsigned long flags; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + +if (list_empty (&events->available)) { +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +return -ENOENT ; + } + +WARN_ON (events->navailable ==0 ); + + kev = list_first_entry(&events->available, struct v4l2_kevent, list); +list_move (&kev->list, &events->free); + events->navailable--; + + kev->event.pending = events->navailable; + *event = kev->event; + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); + +return 0 ;
Quoted 8 lines
drivers/media/video/v4l2-event.c line 132
Quoted 5 lines
drivers/media/video/v4l2-event.c new file +5
-0+} +EXPORT_SYMBOL_GPL (v4l2_event_dequeue); + +static struct v4l2_subscribed_event *v4l2_event_subscribed ( +struct v4l2_fh *fh,u32 type)Add a comment before this function that mentions that
fh->vdev->fh_lockmust be held before calling this.
Ack.
I'll add WARN_ON(!lock_acquired()) as well.
Quoted 28 lines
Quoted 28 lines
drivers/media/video/v4l2-event.c new file +28
-0+{ +struct v4l2_events *events = fh->events; +struct v4l2_subscribed_event *sev; + +list_for_each_entry (sev, &events->subscribed, list) { +if (sev->type == type) +return sev; + } + +return NULL ; +} + +void v4l2_event_queue (struct video_device *vdev,const struct v4l2_event *ev) +{ +struct v4l2_fh *fh; +unsigned long flags; +struct timespec timestamp; + +ktime_get_ts (×tamp); + +spin_lock_irqsave (&vdev->fh_lock, flags); + +list_for_each_entry (fh, &vdev->fh_list, list) { +struct v4l2_events *events = fh->events; +struct v4l2_kevent *kev; +u32 sequence; + +/* Are we subscribed? */
Quoted 8 lines
drivers/media/video/v4l2-event.c line 166
Quoted 6 lines
drivers/media/video/v4l2-event.c new file +6
-0+if (!v4l2_event_subscribed (fh, ev->type)) +continue ; + +/* Increase event sequence number on fh. */ + events->sequence++; + sequence = events->sequence;There is no need for a temp sequence variable...
Good point.
Quoted 41 lines
drivers/media/video/v4l2-event.c line 177
Quoted 11 lines
drivers/media/video/v4l2-event.c new file +11
-0+ +/* Do we have any free events? */ +if (list_empty (&events->free)) +continue ; + +/* Take one and fill it. */ + kev = list_first_entry(&events->free, struct v4l2_kevent, list); + kev->event.type = ev->type; + kev->event.u = ev->u; + kev->event.timestamp = timestamp; + kev->event.sequence = sequence;... you can just use
events->sequencedirectly here.Quoted 14 lines
drivers/media/video/v4l2-event.c new file +14
-0+list_move_tail (&kev->list, &events->available); + + events->navailable++; + +wake_up_all (&events->wait); + } + +spin_unlock_irqrestore (&vdev->fh_lock, flags); +} +EXPORT_SYMBOL_GPL (v4l2_event_queue); + +int v4l2_event_pending (struct v4l2_fh *fh) +{ +return fh->events->navailable;drivers/media/video/v4l2-event.c line 201
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+} +EXPORT_SYMBOL_GPL (v4l2_event_pending); + +int v4l2_event_subscribe (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub) +{ +struct v4l2_events *events = fh->events; +struct v4l2_subscribed_event *sev; +unsigned long flags; +Add this:
Quoted 8 lines
if (events == NULL) { /* If we get here, then the driver forgot to allocate events. */ WARN_ON(1); return -ENOMEM; }If subscribe is called without the event queue being allocated, then the driver did something wrong.
Ok.
Quoted 11 lines
See also my review for patch 5/6.
Quoted 9 lines
drivers/media/video/v4l2-event.c new file +9
-0+ sev =kmalloc (sizeof (*sev),GFP_KERNEL ); +if (!sev) +return -ENOMEM ; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + +if (v4l2_event_subscribed (fh, sub->type) ==NULL ) { +INIT_LIST_HEAD (&sev->list); + sev->type = sub->type;
Quoted 8 lines
drivers/media/video/v4l2-event.c line 215
Quoted 5 lines
drivers/media/video/v4l2-event.c new file +5
-0+ +list_add (&sev->list, &events->subscribed); + } + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags);If the event was already subscribed, then you need to kfree the earlier allocated sev here. Otherwise you have a memory leak.
Thanks for catching this!
No matter how many times you read the code through yourself this kind of bugs may still lie there.
Quoted 30 lines
Quoted 13 lines
drivers/media/video/v4l2-event.c new file +13
-0+ +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_subscribe); + +/* subscribe a zero-terminated array of events */ +int v4l2_event_subscribe_many (struct v4l2_fh *fh,const u32 *all) +{ +int ret; + +for (; *all; all++) { +struct v4l2_event_subscription sub; +drivers/media/video/v4l2-event.c line 238
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+ sub.type = *all; + + ret =v4l2_event_subscribe (fh, &sub); +if (ret) +return ret; + } + +return 0 ; +} +EXPORT_SYMBOL_GPL (v4l2_event_subscribe_many);Supporting
V4L2_EVENT_ALLis a bad idea when subscribing. It sounds nice initially, but the longer I think about it the more convinced I am we should not do this. The main argument is really that it can lead to unexpected behavior. Suppose a userspace application subscribes to all events. And in a later version of the driver new events are added. Suddenly those will also arrive in the userspace app.
Quoted 3 lines
This might cause it to crash if it was written badly and it didn't check against unknown events. Or this new event might be a high-volume event which might flood the application unexpectedly.
Many events are more or less related to the drivers. If an application is unable to cope with events it has subscribed then it's an application problem IMO.
I'm fine with dropping V4L2_EVENT_ALL in subscription. It can always be added later if it's ever required.
Quoted 45 lines
Quoted 12 lines
drivers/media/video/v4l2-event.c new file +12
-0+ +static void v4l2_event_unsubscribe_all (struct v4l2_fh *fh) +{ +struct v4l2_events *events = fh->events; +unsigned long flags; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + +while (!list_empty (&events->subscribed)) { +struct v4l2_subscribed_event *sev; + + sev = list_first_entry(&events->subscribed,drivers/media/video/v4l2-event.c line 260
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+ struct v4l2_subscribed_event, list); + +list_del (&sev->list); +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +kfree (sev); +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + } + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +}What about this:
static void
v4l2_event_unsubscribe_all(struct v4l2_fh *fh){ struct v4l2_events *events = fh->events; struct v4l2_subscribed_event *sev; unsigned long flags; do { sev = NULL; spin_lock_irqsave(&fh->vdev->fh_lock, flags); if (!list_empty(&events->subscribed)) { sev = list_first_entry(&events->subscribed, struct v4l2_subscribed_event, list); list_del(&sev->list); } spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); kfree(sev); } while (sev); }
Quoted 1 line
This avoids the 'interleaved' locking which I never like.
Can do. I don't see anything bad in that kind of locking, though. ;-)
Quoted 16 lines
Quoted 16 lines
drivers/media/video/v4l2-event.c new file +16
-0+ +int v4l2_event_unsubscribe (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub) +{ +struct v4l2_subscribed_event *sev; +unsigned long flags; + +if (sub->type ==V4L2_EVENT_ALL ) { +v4l2_event_unsubscribe_all (fh); +return 0 ; + } + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + + sev =v4l2_event_subscribed (fh, sub->type); +if (sev !=NULL )
Quoted 8 lines
drivers/media/video/v4l2-event.c line 282
Quoted 6 lines
drivers/media/video/v4l2-event.c new file +6
-0+list_del (&sev->list); + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); + +if (sev !=NULL ) +kfree (sev);No need for the NULL check. kfree(NULL) is allowed.
Done.
Quoted 9 lines
include/media/v4l2-event.h line 49
Quoted 6 lines
include/media/v4l2-event.h new file +6
-0+struct v4l2_events { +wait_queue_head_t wait; +struct list_head subscribed;/* Subscribed events */ +struct list_head available;/* Dequeueable event */ +unsigned int navailable; +struct list_head free;/* Events ready for use */ I would move this between the subscribed and available lists. Purely for grouping the lists together.
Done.
Signature · 2 lines
Sakari Ailus [email protected]
Re: [PATCH v5 4/6] V4L: Events: Add backend
Quoted 56 lines · On Sunday 21 February 2010 21:57:47 Sakari Ailus wrote:
Quoted 1 line · Hans Verkuil
Hi Sakari,
Hi Hans,
And many thanks for the comments again!
Quoted 2 lines
Here are some more comments.
...
Quoted 45 lines
Quoted 12 lines
drivers/media/video/v4l2-event.c new file +12
-0+ +static void v4l2_event_unsubscribe_all (struct v4l2_fh *fh) +{ +struct v4l2_events *events = fh->events; +unsigned long flags; + +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + +while (!list_empty (&events->subscribed)) { +struct v4l2_subscribed_event *sev; + + sev = list_first_entry(&events->subscribed,drivers/media/video/v4l2-event.c line 260
Quoted 10 lines
drivers/media/video/v4l2-event.c new file +10
-0+ struct v4l2_subscribed_event, list); + +list_del (&sev->list); +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +kfree (sev); +spin_lock_irqsave (&fh->vdev->fh_lock, flags); + } + +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); +}What about this:
static void
v4l2_event_unsubscribe_all(struct v4l2_fh *fh){ struct v4l2_events *events = fh->events; struct v4l2_subscribed_event *sev; unsigned long flags; do { sev = NULL; spin_lock_irqsave(&fh->vdev->fh_lock, flags); if (!list_empty(&events->subscribed)) { sev = list_first_entry(&events->subscribed, struct v4l2_subscribed_event, list); list_del(&sev->list); } spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); kfree(sev); } while (sev); }
Quoted 3 lines
Quoted 1 line
This avoids the 'interleaved' locking which I never like.
Can do. I don't see anything bad in that kind of locking, though. ;-)
Locking is hard to get right. So it is important to keep the locking code as straightforward as possible. In the original code you really have to look closely at the code to check that the locking is correct. In the rewritten code it is much more obvious because of the simplified control flow.
Regards,
Hans
Signature · 1 line
Hans Verkuil - video4linux developer - sponsored by TANDBERG
PATCH v5 5/6 V4L: Events: Support event handling in do_ioctl
In reply to Sakari AilusAdd support for event handling to do_ioctl.
--- drivers/media/video/v4l2-ioctl.c | 58 ++++++++++++++++++++++++++++++++++++++ include/media/v4l2-ioctl.h | 7 ++++ 2 files changed, 65 insertions(+), 0 deletions(-)
drivers/media/video/v4l2-ioctl.c +58 -0
@@ -25,6 +25,8 @@#endif #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> #include <media/v4l2-chip-ident.h> #define dbgarg(cmd, fmt, arg...) \
@@ -1944,7 +1946,63 @@ static long __video_do_ioctl(struct file *file, }break ; } +case VIDIOC_DQEVENT : + { +struct v4l2_event *ev = arg; +struct v4l2_fh *vfh = fh; + +if (!test_bit (V4L2_FL_USES_V4L2_FH , &vfd->flags) + || vfh->events ==NULL ) +break ; + + ret =v4l2_event_dequeue (fh, ev); +if (ret <0 ) { +dbgarg (cmd,"no pending events?" ); +break ; + } +dbgarg (cmd, +"pending=%d, type=0x%8.8x, sequence=%d, " +"timestamp=%lu.%9.9lu " , + ev->pending, ev->type, ev->sequence, + ev->timestamp.tv_sec, ev->timestamp.tv_nsec); +break ; + } +case VIDIOC_SUBSCRIBE_EVENT : + { +struct v4l2_event_subscription *sub = arg; +struct v4l2_fh *vfh = fh; +if (!test_bit (V4L2_FL_USES_V4L2_FH , &vfd->flags) + || vfh->events ==NULL + || !ops->vidioc_subscribe_event) +break ; + + ret = ops->vidioc_subscribe_event (fh, sub); +if (ret <0 ) { +dbgarg (cmd,"failed, ret=%ld" , ret); +break ; + } +dbgarg (cmd,"type=0x%8.8x" , sub->type); +break ; + } +case VIDIOC_UNSUBSCRIBE_EVENT : + { +struct v4l2_event_subscription *sub = arg; +struct v4l2_fh *vfh = fh; + +if (!test_bit (V4L2_FL_USES_V4L2_FH , &vfd->flags) + || vfh->events ==NULL + || !ops->vidioc_unsubscribe_event) +break ; + + ret = ops->vidioc_unsubscribe_event (fh, sub); +if (ret <0 ) { +dbgarg (cmd,"failed, ret=%ld" , ret); +break ; + } +dbgarg (cmd,"type=0x%8.8x" , sub->type); +break ; + }default : {if (!ops->vidioc_default)
include/media/v4l2-ioctl.h +7 -0
@@ -21,6 +21,8 @@#include <linux/videodev2.h> #endif +struct v4l2_fh ; +struct v4l2_ioctl_ops {/* ioctl callbacks */
@@ -254,6 +256,11 @@ struct v4l2_ioctl_ops {int (*vidioc_g_dv_timings) (struct file *file,void *fh,struct v4l2_dv_timings *timings); +int (*vidioc_subscribe_event) (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub); +int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh, +struct v4l2_event_subscription *sub); +/* For other private ioctls */ long (*vidioc_default) (struct file *file,void *fh,int cmd,void *arg);
Signature · 1 line
1.5.6.5
Re: [PATCH v5 5/6] V4L: Events: Support event handling in do_ioctl
More comments...
Quoted 23 lines · On Friday 19 February 2010 20:21:59 Sakari Ailus wrote:
Add support for event handling to
do_ioctl.Signed-off-by Sakari Ailus <[email protected]>--- drivers/media/video/v4l2-ioctl.c | 58 ++++++++++++++++++++++++++++++++++++++ include/media/v4l2-ioctl.h | 7 ++++ 2 files changed, 65 insertions(+), 0 deletions(-)drivers/media/video/v4l2-ioctl.c +2
-0@@ -25,6 +25,8 @@#endif #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> #include <media/v4l2-chip-ident.h> #define dbgarg(cmd, fmt, arg...) \@@ -1944,7 +1946,63 @@ static long __video_do_ioctl(struct file *file, }
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1956
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +8
-0break ; } +case VIDIOC_DQEVENT : + { +struct v4l2_event *ev = arg; +struct v4l2_fh *vfh = fh; + +if (!test_bit (V4L2_FL_USES_V4L2_FH , &vfd->flags) + || vfh->events ==NULL ) +break ;
Change this to:
if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) break; if (vfh->events == NULL) return -ENOENT;
But see also the next comment.
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1958
Quoted 2 lines
drivers/media/video/v4l2-ioctl.c +2
-0+ + ret =v4l2_event_dequeue (fh, ev);
There is a crucial piece of functionality missing here: if the filehandle is in blocking mode, then it should wait until an event arrives. That also means that if vfh->events == NULL, you should still call v4l2_event_dequeue, and that function should initialize vfh->events and wait for an event if the fh is in blocking mode.
So I would remove the events == NULL test here and just call v4l2_event_dequeue and let that function handle it.
Quoted 7 lines
drivers/media/video/v4l2-ioctl.c +7
-0+if (ret <0 ) { +dbgarg (cmd,"no pending events?" ); +break ; + } + dbgarg(cmd, + "pending=%d, type=0x%8.8x, sequence=%d, " + "timestamp=%lu.%9.9lu ",
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1975
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +9
-0+ ev->pending, ev->type, ev->sequence, + ev->timestamp.tv_sec, ev->timestamp.tv_nsec); +break ; + } +case VIDIOC_SUBSCRIBE_EVENT : + { +struct v4l2_event_subscription *sub = arg; +struct v4l2_fh *vfh = fh; + if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)
Testing for this bit is unnecessarily. Just test for ops->vidioc_subscribe_event.
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1976
Quoted 1 line
drivers/media/video/v4l2-ioctl.c +1
-0+ || vfh->events == NULL
Remove this test. If you allocate the event queue only when you first subscribe to an event (as ivtv will do), then you have to be able to call vidioc_subscribe_event even if vfh->events == NULL.
Quoted 9 lines
drivers/media/video/v4l2-ioctl.c +9
-0+ || !ops->vidioc_subscribe_event) +break ; + + ret = ops->vidioc_subscribe_event (fh, sub); +if (ret <0 ) { +dbgarg (cmd,"failed, ret=%ld" , ret); +break ; + } +dbgarg (cmd,"type=0x%8.8x" , sub->type);
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1995
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +10
-0+break ; + } +case VIDIOC_UNSUBSCRIBE_EVENT : + { +struct v4l2_event_subscription *sub = arg; +struct v4l2_fh *vfh = fh; + +if (!test_bit (V4L2_FL_USES_V4L2_FH , &vfd->flags) + || vfh->events ==NULL + || !ops->vidioc_unsubscribe_event)
No need for the test_bit. This is sufficient:
if (!ops->vidioc_unsubscribe_event || vfh->events == NULL)
Note that I am not so keen on testing against vfh->events here. I consider this a v4l2_fh-internal field that should not be used outside the v4l2_event_ and v4l2_fh_ functions.
Quoted 29 lines
drivers/media/video/v4l2-ioctl.c +10
-0+break ; + + ret = ops->vidioc_unsubscribe_event (fh, sub); +if (ret <0 ) { +dbgarg (cmd,"failed, ret=%ld" , ret); +break ; + } +dbgarg (cmd,"type=0x%8.8x" , sub->type); +break ; + }default : {if (!ops->vidioc_default)include/media/v4l2-ioctl.h +2
-0@@ -21,6 +21,8 @@#include <linux/videodev2.h> #endif +struct v4l2_fh ; +struct v4l2_ioctl_ops {/* ioctl callbacks */ @@ -254,6 +256,11 @@ struct v4l2_ioctl_ops { int (*vidioc_g_dv_timings) (struct file *file, void *fh,
include/media/v4l2-ioctl.h struct v4l2_ioctl_ops { · line 266
Quoted 10 lines
include/media/v4l2-ioctl.h +5
-0struct v4l2_dv_timings *timings); +int (*vidioc_subscribe_event) (struct v4l2_fh *fh, +struct v4l2_event_subscription *sub); +int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh, +struct v4l2_event_subscription *sub); +/* For other private ioctls */ long (*vidioc_default) (struct file *file,void *fh,int cmd,void *arg);
Regards,
Hans
Signature · 1 line
Hans Verkuil - video4linux developer - sponsored by TANDBERG
Re: [PATCH v5 5/6] V4L: Events: Support event handling in do_ioctl
Quoted 46 lines · Hans Verkuil
More comments...
Quoted 23 lines · On Friday 19 February 2010 20:21:59 Sakari Ailus wrote:
Add support for event handling to
do_ioctl.Signed-off-by Sakari Ailus <[email protected]>--- drivers/media/video/v4l2-ioctl.c | 58 ++++++++++++++++++++++++++++++++++++++ include/media/v4l2-ioctl.h | 7 ++++ 2 files changed, 65 insertions(+), 0 deletions(-)drivers/media/video/v4l2-ioctl.c +2
-0@@ -25,6 +25,8 @@#endif #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> #include <media/v4l2-chip-ident.h> #define dbgarg(cmd, fmt, arg...) \@@ -1944,7 +1946,63 @@ static long __video_do_ioctl(struct file *file, }drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1956
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +8
-0break ; } +case VIDIOC_DQEVENT : + { +struct v4l2_event *ev = arg; +struct v4l2_fh *vfh = fh; + +if (!test_bit (V4L2_FL_USES_V4L2_FH , &vfd->flags) + || vfh->events ==NULL ) +break ;Change this to:
if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) break; if (vfh->events == NULL) return -ENOENT;But see also the next comment.
Quoted 8 lines
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1958
Quoted 2 lines
drivers/media/video/v4l2-ioctl.c +2
-0+ + ret =v4l2_event_dequeue (fh, ev);There is a crucial piece of functionality missing here: if the filehandle is in blocking mode, then it should wait until an event arrives. That also means that if
vfh->events== NULL, you should still callv4l2_event_dequeue, and that function should initializevfh->eventsand wait for an event if the fh is in blocking mode.
I originally left this out intentionally. Most applications using events would use select / poll as well by default. For completeness it should be there, I agree.
This btw. suggests that we perhaps should put back the struct file argument for the event functions in video_ioctl_ops. The blocking flag is indeed part of the file structure. I'm open to better suggestions, too.
Quoted 20 lines
Quoted 7 lines
drivers/media/video/v4l2-ioctl.c +7
-0+if (ret <0 ) { +dbgarg (cmd,"no pending events?" ); +break ; + } + dbgarg(cmd, + "pending=%d, type=0x%8.8x, sequence=%d, " + "timestamp=%lu.%9.9lu ",drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1975
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +9
-0+ ev->pending, ev->type, ev->sequence, + ev->timestamp.tv_sec, ev->timestamp.tv_nsec); +break ; + } +case VIDIOC_SUBSCRIBE_EVENT : + { +struct v4l2_event_subscription *sub = arg; +struct v4l2_fh *vfh = fh; + if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)Testing for this bit is unnecessarily. Just test for
ops->vidioc_subscribe_event.
Quoted 5 lines
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1976
Quoted 1 line
drivers/media/video/v4l2-ioctl.c +1
-0+ || vfh->events == NULLRemove this test. If you allocate the event queue only when you first subscribe to an event (as ivtv will do), then you have to be able to call
vidioc_subscribe_eventeven ifvfh->events== NULL.
How about calling v4l2_event_alloc() with zero events? That allocates and initialises the v4l2_events structure. That's easier to handle in drivers as well since they don't need to consider special cases like fh->events happens to be NULL even if events are supported by the driver. This is how I first thought it'd work.
Signature · 2 lines
Sakari Ailus [email protected]
Re: [PATCH v5 5/6] V4L: Events: Support event handling in do_ioctl
Hi Sakari,
Quoted 67 lines · On Sunday 21 February 2010 23:31:43 Sakari Ailus wrote:
Quoted 57 lines · Hans Verkuil
More comments...
Quoted 32 lines · On Friday 19 February 2010 20:21:59 Sakari Ailus wrote:
Add support for event handling to
do_ioctl.Signed-off-by Sakari Ailus <[email protected]>---
drivers/media/video/v4l2-ioctl.c | 58 ++++++++++++++++++++++++++++++++++++++ include/media/v4l2-ioctl.h | 7 ++++ 2 files changed, 65 insertions(+), 0 deletions(-)(quoted diff) +0
-0
b/drivers/media/video/v4l2-ioctl.cindex 34c7d6e..f7d6177 100644drivers/media/video/v4l2-ioctl.c +2
-0@@ -25,6 +25,8 @@#endif #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> #include <
media/v4l2-chip-ident.h>#define
dbgarg(cmd, fmt, arg...)\drivers/media/video/v4l2-ioctl.c +0
-0@@ -1944,7 +1946,63 @@ static long __video_do_ioctl(struct file *file, }break ;drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1959
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +8
-0} +case VIDIOC_DQEVENT : + { +struct v4l2_event *ev = arg; +struct v4l2_fh *vfh = fh; + +if (!test_bit (V4L2_FL_USES_V4L2_FH , &vfd->flags) + || vfh->events ==NULL ) +break ;Change this to:
if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) break; if (vfh->events == NULL) return -ENOENT;But see also the next comment.
Quoted 8 lines
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1961
Quoted 2 lines
drivers/media/video/v4l2-ioctl.c +2
-0+ + ret =v4l2_event_dequeue (fh, ev);There is a crucial piece of functionality missing here: if the filehandle is in blocking mode, then it should wait until an event arrives. That also means that if
vfh->events== NULL, you should still callv4l2_event_dequeue, and that function should initializevfh->eventsand wait for an event if the fh is in blocking mode.
Quoted 7 lines
I originally left this out intentionally. Most applications using events would use select / poll as well by default. For completeness it should be there, I agree.
This btw. suggests that we perhaps should put back the struct file argument for the event functions in
video_ioctl_ops. The blocking flag is indeed part of the file structure. I'm open to better suggestions, too.
If the only information we need from struct file is the flags, they could be copied to v4l2_fh in the open handler. We could also put a struct file * member in v4l2_fh.
Signature · 3 lines
Regards, Laurent Pinchart
Re: [PATCH v5 5/6] V4L: Events: Support event handling in do_ioctl
Quoted 1 line · Laurent Pinchart
Hi Sakari,
Salut Laurent,
Quoted 10 lines
Quoted 10 lines
Quoted 5 lines
There is a crucial piece of functionality missing here: if the filehandle is in blocking mode, then it should wait until an event arrives. That also means that if
vfh->events== NULL, you should still callv4l2_event_dequeue, and that function should initializevfh->eventsand wait for an event if the fh is in blocking mode.I originally left this out intentionally. Most applications using events would use select / poll as well by default. For completeness it should be there, I agree.
Quoted 7 lines
Quoted 3 lines
This btw. suggests that we perhaps should put back the struct file argument for the event functions in
video_ioctl_ops. The blocking flag is indeed part of the file structure. I'm open to better suggestions, too.If the only information we need from struct file is the flags, they could be copied to
v4l2_fhin the open handler. We could also put a struct file * member inv4l2_fh.
That could be one possibility. Copying the flags in open() isn't enough as they can change as a result of fcntl call. As we're not handling that call the flags in struct v4l2_fh would have to be updated for every ioctl. I'm not a big fan of caching information in general either. :-) I could accept this, though.
Signature · 2 lines
Sakari Ailus [email protected]
Re: [PATCH v5 5/6] V4L: Events: Support event handling in do_ioctl
In reply to Sakari AilusQuoted 56 lines · On Sunday 21 February 2010 23:31:43 Sakari Ailus wrote:
Quoted 46 lines · Hans Verkuil
More comments...
Quoted 23 lines · On Friday 19 February 2010 20:21:59 Sakari Ailus wrote:
Add support for event handling to
do_ioctl.Signed-off-by Sakari Ailus <[email protected]>--- drivers/media/video/v4l2-ioctl.c | 58 ++++++++++++++++++++++++++++++++++++++ include/media/v4l2-ioctl.h | 7 ++++ 2 files changed, 65 insertions(+), 0 deletions(-)drivers/media/video/v4l2-ioctl.c +2
-0@@ -25,6 +25,8 @@#endif #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> #include <media/v4l2-chip-ident.h> #define dbgarg(cmd, fmt, arg...) \@@ -1944,7 +1946,63 @@ static long __video_do_ioctl(struct file *file, }drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1956
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +8
-0break ; } +case VIDIOC_DQEVENT : + { +struct v4l2_event *ev = arg; +struct v4l2_fh *vfh = fh; + +if (!test_bit (V4L2_FL_USES_V4L2_FH , &vfd->flags) + || vfh->events ==NULL ) +break ;Change this to:
if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) break; if (vfh->events == NULL) return -ENOENT;But see also the next comment.
Quoted 8 lines
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1958
Quoted 2 lines
drivers/media/video/v4l2-ioctl.c +2
-0+ + ret =v4l2_event_dequeue (fh, ev);There is a crucial piece of functionality missing here: if the filehandle is in blocking mode, then it should wait until an event arrives. That also means that if
vfh->events== NULL, you should still callv4l2_event_dequeue, and that function should initializevfh->eventsand wait for an event if the fh is in blocking mode.
Quoted 3 lines
I originally left this out intentionally. Most applications using events would use select / poll as well by default. For completeness it should be there, I agree.
It has to be there. This is important functionality. For e.g. ivtv I would use this to wait until the MPEG decoder flushed all buffers and displayed the last frame of the stream. That's something you would often do in blocking mode.
Quoted 3 lines
This btw. suggests that we perhaps should put back the struct file argument for the event functions in
video_ioctl_ops. The blocking flag is indeed part of the file structure. I'm open to better suggestions, too.
My long term goal is that the file struct is only used inside v4l2-ioctl.c and not in drivers. Drivers should not need this struct at all. The easiest way to ensure this is by not passing it to the drivers at all :-)
Quoted 26 lines
Quoted 20 lines
Quoted 7 lines
drivers/media/video/v4l2-ioctl.c +7
-0+if (ret <0 ) { +dbgarg (cmd,"no pending events?" ); +break ; + } + dbgarg(cmd, + "pending=%d, type=0x%8.8x, sequence=%d, " + "timestamp=%lu.%9.9lu ",drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1975
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +9
-0+ ev->pending, ev->type, ev->sequence, + ev->timestamp.tv_sec, ev->timestamp.tv_nsec); +break ; + } +case VIDIOC_SUBSCRIBE_EVENT : + { +struct v4l2_event_subscription *sub = arg; +struct v4l2_fh *vfh = fh; + if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)Testing for this bit is unnecessarily. Just test for
ops->vidioc_subscribe_event.Quoted 5 lines
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1976
Quoted 1 line
drivers/media/video/v4l2-ioctl.c +1
-0+ || vfh->events == NULLRemove this test. If you allocate the event queue only when you first subscribe to an event (as ivtv will do), then you have to be able to call
vidioc_subscribe_eventeven ifvfh->events== NULL.
Quoted 5 lines
How about calling
v4l2_event_alloc()with zero events? That allocates and initialises thev4l2_eventsstructure. That's easier to handle in drivers as well since they don't need to consider special cases likefh->eventshappens to be NULL even if events are supported by the driver. This is how I first thought it'd work.
Proposal: export a v4l2_event_init() call that sets up fh->events. Calling v4l2_event_alloc(0) feels like a hack. So drivers that want to be able to handle events should call v4l2_event_init after initializing the file handle.
Or (and that might even be nicer) test in v4l2_fh_init whether there is a subscribe op in the ioctl_ops struct and let v4l2_fh_init set up fh->events automatically.
Regards,
Hans
Signature · 1 line
Hans Verkuil - video4linux developer - sponsored by TANDBERG
Re: [PATCH v5 5/6] V4L: Events: Support event handling in do_ioctl
Hi Hans,
Quoted 68 lines · On Monday 22 February 2010 08:53:53 Hans Verkuil wrote:
Quoted 67 lines · On Sunday 21 February 2010 23:31:43 Sakari Ailus wrote:
Quoted 65 lines · Hans Verkuil
More comments...
Quoted 32 lines · On Friday 19 February 2010 20:21:59 Sakari Ailus wrote:
Add support for event handling to
do_ioctl.Signed-off-by Sakari Ailus <[email protected]>---
drivers/media/video/v4l2-ioctl.c | 58 ++++++++++++++++++++++++++++++++++++++ include/media/v4l2-ioctl.h | 7 ++++ 2 files changed, 65 insertions(+), 0 deletions(-)(quoted diff) +0
-0
b/drivers/media/video/v4l2-ioctl.cindex 34c7d6e..f7d6177 100644drivers/media/video/v4l2-ioctl.c +2
-0@@ -25,6 +25,8 @@#endif #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> #include <
media/v4l2-chip-ident.h>#define
dbgarg(cmd, fmt, arg...)\drivers/media/video/v4l2-ioctl.c +0
-0@@ -1944,7 +1946,63 @@ static long __video_do_ioctl(struct file *file, }break ;drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1959
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +8
-0} +case VIDIOC_DQEVENT : + { +struct v4l2_event *ev = arg; +struct v4l2_fh *vfh = fh; + +if (!test_bit (V4L2_FL_USES_V4L2_FH , &vfd->flags) + || vfh->events ==NULL ) +break ;Change this to:
if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) break; if (vfh->events == NULL) return -ENOENT;But see also the next comment.
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1961
Quoted 2 lines
drivers/media/video/v4l2-ioctl.c +2
-0+ + ret =v4l2_event_dequeue (fh, ev);There is a crucial piece of functionality missing here: if the filehandle is in blocking mode, then it should wait until an event arrives. That also means that if
vfh->events== NULL, you should still callv4l2_event_dequeue, and that function should initializevfh->eventsand wait for an event if the fh is in blocking mode.
Quoted 8 lines
Quoted 3 lines
I originally left this out intentionally. Most applications using events would use select / poll as well by default. For completeness it should be there, I agree.
It has to be there. This is important functionality. For e.g. ivtv I would use this to wait until the MPEG decoder flushed all buffers and displayed the last frame of the stream. That's something you would often do in blocking mode.
Blocking mode can easily be emulated using select().
Quoted 8 lines
Quoted 4 lines
This btw. suggests that we perhaps should put back the struct file argument for the event functions in
video_ioctl_ops. The blocking flag is indeed part of the file structure. I'm open to better suggestions, too.My long term goal is that the file struct is only used inside
v4l2-ioctl.cand not in drivers. Drivers should not need this struct at all. The easiest way to ensure this is by not passing it to the drivers at all :-)
Drivers still need a way to access the blocking flag. The interim solution of adding a file * member to v4l2_fh would allow that, while still removing most usage of file * from drivers.
Quoted 41 lines
Quoted 27 lines
Quoted 21 lines
Quoted 7 lines
drivers/media/video/v4l2-ioctl.c +7
-0+if (ret <0 ) { +dbgarg (cmd,"no pending events?" ); +break ; + } + dbgarg(cmd, + "pending=%d, type=0x%8.8x, sequence=%d, " + "timestamp=%lu.%9.9lu ",drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1975
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +9
-0+ ev->pending, ev->type, ev->sequence, + ev->timestamp.tv_sec, ev->timestamp.tv_nsec); +break ; + } +case VIDIOC_SUBSCRIBE_EVENT : + { +struct v4l2_event_subscription *sub = arg; +struct v4l2_fh *vfh = fh; + if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)Testing for this bit is unnecessarily. Just test for
ops->vidioc_subscribe_event.Quoted 5 lines
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1979
Quoted 1 line
drivers/media/video/v4l2-ioctl.c +1
-0+ || vfh->events == NULLRemove this test. If you allocate the event queue only when you first subscribe to an event (as ivtv will do), then you have to be able to call
vidioc_subscribe_eventeven ifvfh->events== NULL.Quoted 5 lines
How about calling
v4l2_event_alloc()with zero events? That allocates and initialises thev4l2_eventsstructure. That's easier to handle in drivers as well since they don't need to consider special cases likefh->eventshappens to be NULL even if events are supported by the driver. This is how I first thought it'd work.Proposal: export a
v4l2_event_init()call that sets upfh->events. Callingv4l2_event_alloc(0)feels like a hack. So drivers that want to be able to handle events should callv4l2_event_initafter initializing the file handle.Or (and that might even be nicer) test in
v4l2_fh_initwhether there is a subscribe op in theioctl_opsstruct and letv4l2_fh_initset upfh->eventsautomatically.
Signature · 3 lines
Regards, Laurent Pinchart
Re: [PATCH v5 5/6] V4L: Events: Support event handling in do_ioctl
Quoted 100 lines
Hi Hans,
Quoted 76 lines · On Monday 22 February 2010 08:53:53 Hans Verkuil wrote:
Quoted 7 lines · On Sunday 21 February 2010 23:31:43 Sakari Ailus wrote:
Quoted 6 lines · Hans Verkuil
More comments...
Quoted 3 lines · On Friday 19 February 2010 20:21:59 Sakari Ailus wrote:
Add support for event handling to
do_ioctl.Signed-off-by Sakari AilusQuoted 17 lines
Quoted 17 lines
Quoted 17 lines
---
drivers/media/video/v4l2-ioctl.c | 58 ++++++++++++++++++++++++++++++++++++++ include/media/v4l2-ioctl.h | 7 ++++ 2 files changed, 65 insertions(+), 0 deletions(-)(quoted diff) +0
-0
b/drivers/media/video/v4l2-ioctl.cindex 34c7d6e..f7d6177 100644drivers/media/video/v4l2-ioctl.c +0
-0@@ -25,6 +25,8 @@#endif #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> Quoted 8 lines
Quoted 8 lines
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file
Quoted 8 lines
drivers/media/video/v4l2-ioctl.c +2
-0+#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> #include <
media/v4l2-chip-ident.h>#define
dbgarg(cmd, fmt, arg...)\drivers/media/video/v4l2-ioctl.c +0
-0@@ -1944,7 +1946,63 @@ static long __video_do_ioctl(struct file*file,
Quoted 24 lines
Quoted 24 lines
Quoted 4 lines
drivers/media/video/v4l2-ioctl.c +0
-0}break ;drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file *file, · line 1956
Quoted 10 lines
drivers/media/video/v4l2-ioctl.c +8
-0} +case VIDIOC_DQEVENT : + { +struct v4l2_event *ev = arg; +struct v4l2_fh *vfh = fh; + +if (!test_bit (V4L2_FL_USES_V4L2_FH , &vfd->flags) + || vfh->events ==NULL ) +break ;Change this to:
if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) break; if (vfh->events == NULL) return -ENOENT;Quoted 8 lines
Quoted 8 lines
But see also the next comment.
drivers/media/video/v4l2-ioctl.c static long __video_do_ioctl(struct file · line 1960
Quoted 2 lines
drivers/media/video/v4l2-ioctl.c +2
-0+ + ret =v4l2_event_dequeue (fh, ev);There is a crucial piece of functionality missing here: if the filehandle is in blocking mode, then it should wait until an event arrives. That also means that if
vfh->events== NULL, you shouldstill
Quoted 4 lines
Quoted 2 lines
call
v4l2_event_dequeue, and that function should initializevfh->eventsand wait for an event if the fh is in blocking mode.I originally left this out intentionally. Most applications using
events
Quoted 2 lines
would use select / poll as well by default. For completeness it should be there, I agree.
Quoted 6 lines
It has to be there. This is important functionality. For e.g. ivtv I would
use this to wait until the MPEG decoder flushed all buffers and displayed
the last frame of the stream. That's something you would often do in blocking mode.Blocking mode can easily be emulated using
select().Quoted 10 lines
Quoted 4 lines
This btw. suggests that we perhaps should put back the struct file argument for the event functions in
video_ioctl_ops. The blocking flag is indeed part of the file structure. I'm open to better suggestions, too.My long term goal is that the file struct is only used inside
v4l2-ioctl.c
and not in drivers. Drivers should not need this struct at all. The easiest
way to ensure this is by not passing it to the drivers at all :-)
Quoted 5 lines
Drivers still need a way to access the blocking flag. The interim solution of
adding a file * member tov4l2_fhwould allow that, while still removing most
usage of file * from drivers.
Why not just add a 'blocking' argument to the v4l2_event_dequeue? And let v4l2-ioctl.c fill in that argument? That's how I would do it.
Regards,
Hans
Signature · 1 line
Hans Verkuil - video4linux developer - sponsored by TANDBERG Telecom
Re: [PATCH v5 5/6] V4L: Events: Support event handling in do_ioctl
Quoted 12 lines · Hans Verkuil
Quoted 12 lines
Quoted 12 lines
Quoted 3 lines
Quoted 3 lines
There is a crucial piece of functionality missing here: if the filehandle is in blocking mode, then it should wait until an event arrives. That also means that if
vfh->events== NULL, you shouldstill
Quoted 4 lines
Quoted 2 lines
call
v4l2_event_dequeue, and that function should initializevfh->eventsand wait for an event if the fh is in blocking mode.I originally left this out intentionally. Most applications using
events
Quoted 2 lines
would use select / poll as well by default. For completeness it should be there, I agree.
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
It has to be there. This is important functionality. For e.g. ivtv I would
use this to wait until the MPEG decoder flushed all buffers and displayed
the last frame of the stream. That's something you would often do in blocking mode.Blocking mode can easily be emulated using
select().
It's quite simple to implement still so I'll do that in the VIDIOC_DQEVENT. Easier for applications anyway in use cases that I haven't been thinking about, e.g. ivtv.
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Quoted 4 lines
This btw. suggests that we perhaps should put back the struct file argument for the event functions in
video_ioctl_ops. The blocking flag is indeed part of the file structure. I'm open to better suggestions, too.My long term goal is that the file struct is only used inside
v4l2-ioctl.c
and not in drivers. Drivers should not need this struct at all. The easiest
way to ensure this is by not passing it to the drivers at all :-)
Quoted 8 lines
Quoted 5 lines
Drivers still need a way to access the blocking flag. The interim solution of
adding a file * member tov4l2_fhwould allow that, while still removing most
usage of file * from drivers.Why not just add a 'blocking' argument to the
v4l2_event_dequeue? And letv4l2-ioctl.cfill in that argument? That's how I would do it.
Implemented already before reading your mail... :-) I'll try to repost the patches today.
Signature · 2 lines
Sakari Ailus [email protected]
PATCH v5 6/6 V4L: Events: Add documentation
In reply to Sakari AilusAdd documentation on how to use V4L2 events, both for V4L2 drivers and for V4L2 applications.
--- Documentation/DocBook/media-entities.tmpl | 9 ++ Documentation/DocBook/v4l/dev-event.xml | 34 ++++++ Documentation/DocBook/v4l/v4l2.xml | 3 + Documentation/DocBook/v4l/vidioc-dqevent.xml | 124 ++++++++++++++++++++ .../DocBook/v4l/vidioc-subscribe-event.xml | 109 +++++++++++++++++ Documentation/video4linux/v4l2-framework.txt | 43 +++++++ 6 files changed, 322 insertions(+), 0 deletions(-) create mode 100644 Documentation/DocBook/v4l/dev-event.xml create mode 100644 Documentation/DocBook/v4l/vidioc-dqevent.xml create mode 100644 Documentation/DocBook/v4l/vidioc-subscribe-event.xml
Documentation/DocBook/media-entities.tmpl +9 -0
@@ -17,6 +17,7 @@ <!ENTITY VIDIOC-DBG-G-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_G_REGISTER</constant></link>"> <!ENTITY VIDIOC-DBG-S-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_S_REGISTER</constant></link>"> <!ENTITY VIDIOC-DQBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_DQBUF</constant></link>"> +<!ENTITY VIDIOC-DQEVENT "<link linkend='vidioc-dqevent'><constant>VIDIOC_DQEVENT</constant></link>"> <!ENTITY VIDIOC-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_ENCODER_CMD</constant></link>"> <!ENTITY VIDIOC-ENUMAUDIO "<link linkend='vidioc-enumaudio'><constant>VIDIOC_ENUMAUDIO</constant></link>"> <!ENTITY VIDIOC-ENUMAUDOUT "<link linkend='vidioc-enumaudioout'><constant>VIDIOC_ENUMAUDOUT</constant></link>">
@@ -60,6 +61,7 @@ <!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>"> <!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>"> <!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>"> +<!ENTITY VIDIOC-SUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_SUBSCRIBE_EVENT</constant></link>"> <!ENTITY VIDIOC-S-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_S_AUDIO</constant></link>"> <!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>"> <!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>">
@@ -141,6 +143,8 @@ <!ENTITY v4l2-enc-idx "struct <link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>"> <!ENTITY v4l2-enc-idx-entry "struct <link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>"> <!ENTITY v4l2-encoder-cmd "struct <link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>"> +<!ENTITY v4l2-event "struct <link linkend='v4l2-event'>v4l2_event</link>"> +<!ENTITY v4l2-event-subscription "struct <link linkend='v4l2-event-subscription'>v4l2_event_subscription</link>"> <!ENTITY v4l2-ext-control "struct <link linkend='v4l2-ext-control'>v4l2_ext_control</link>"> <!ENTITY v4l2-ext-controls "struct <link linkend='v4l2-ext-controls'>v4l2_ext_controls</link>"> <!ENTITY v4l2-fmtdesc "struct <link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link>">
@@ -200,6 +204,7 @@ <!ENTITY sub-controls SYSTEM "v4l/controls.xml"> <!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml"> <!ENTITY sub-dev-codec SYSTEM "v4l/dev-codec.xml"> +<!ENTITY sub-dev-event SYSTEM "v4l/dev-event.xml"> <!ENTITY sub-dev-effect SYSTEM "v4l/dev-effect.xml"> <!ENTITY sub-dev-osd SYSTEM "v4l/dev-osd.xml"> <!ENTITY sub-dev-output SYSTEM "v4l/dev-output.xml">
@@ -292,6 +297,8 @@ <!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml"> <!ENTITY sub-videodev2-h SYSTEM "v4l/videodev2.h.xml"> <!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml"> +<!ENTITY sub-dqevent SYSTEM "v4l/vidioc-dqevent.xml"> +<!ENTITY sub-subscribe-event SYSTEM "v4l/vidioc-subscribe-event.xml"> <!ENTITY sub-intro SYSTEM "dvb/intro.xml"> <!ENTITY sub-frontend SYSTEM "dvb/frontend.xml"> <!ENTITY sub-dvbproperty SYSTEM "dvb/dvbproperty.xml">
@@ -381,3 +388,5 @@ <!ENTITY reqbufs SYSTEM "v4l/vidioc-reqbufs.xml"> <!ENTITY s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml"> <!ENTITY streamon SYSTEM "v4l/vidioc-streamon.xml"> +<!ENTITY dqevent SYSTEM "v4l/vidioc-dqevent.xml"> +<!ENTITY subscribe_event SYSTEM "v4l/vidioc-subscribe-event.xml">
Documentation/DocBook/v4l/dev-event.xml new file +34 -0
@@ -0,0 +1,34 @@ + <title>Event Interface</title> + + <para>The V4L2 event interface provides means for user to get + immediately notified on certain conditions taking place on a device. + This might include start of frame or loss of signal events, for + example. + </para> + + <para>To receive events, the events the user is interested first + must be subscribed using the &VIDIOC-SUBSCRIBE-EVENT; ioctl. Once an + event is subscribed, the events of subscribed types are dequeueable + using the &VIDIOC-DQEVENT; ioctl. Events may be unsubscribed using + VIDIOC_UNSUBSCRIBE_EVENT ioctl. The special event type + V4L2_EVENT_ALL may be used to subscribe or unsubscribe all the + events the driver supports.</para> + + <para>The event subscriptions and event queues are specific to file + handles. Subscribing an event on one file handle does not affect + other file handles. + </para> + + <para>The information on dequeueable events are obtained by using + select or poll system calls on video devices. The V4L2 events use + POLLPRI events on poll system call and exceptions on select system + call. + </para> + + <!-- +Local Variables: +mode: sgml +sgml-parent-document: "v4l2.sgml" +indent-tabs-mode: nil +End: + -->
Documentation/DocBook/v4l/v4l2.xml +3 -0
@@ -401,6 +401,7 @@ and discussions on the V4L mailing list.</revremark> <section id="ttx"> &sub-dev-teletext; </section> <section id="radio"> &sub-dev-radio; </section> <section id="rds"> &sub-dev-rds; </section> + <section id="event"> &sub-dev-event; </section> </chapter> <chapter id="driver">
@@ -426,6 +427,7 @@ and discussions on the V4L mailing list.</revremark> &sub-cropcap; &sub-dbg-g-chip-ident; &sub-dbg-g-register; + &sub-dqevent; &sub-encoder-cmd; &sub-enumaudio; &sub-enumaudioout;
@@ -467,6 +469,7 @@ and discussions on the V4L mailing list.</revremark> &sub-reqbufs; &sub-s-hw-freq-seek; &sub-streamon; + &sub-subscribe-event; <!-- End of ioctls. --> &sub-mmap; &sub-munmap;
Documentation/DocBook/v4l/vidioc-dqevent.xml new file +124 -0
124 lines not on this page · raw message
Documentation/DocBook/v4l/vidioc-subscribe-event.xml new file +109 -0
109 lines not on this page · raw message
Documentation/video4linux/v4l2-framework.txt +43 -0
46 lines not on this page · raw message
Signature · 1 line
1.5.6.5
Re: [PATCH v5 6/6] V4L: Events: Add documentation
Quoted 315 lines · On Friday 19 February 2010 20:22:00 Sakari Ailus wrote:
Add documentation on how to use V4L2 events, both for V4L2 drivers and for V4L2 applications.
Signed-off-by Sakari Ailus <[email protected]>--- Documentation/DocBook/media-entities.tmpl | 9 ++ Documentation/DocBook/v4l/dev-event.xml | 34 ++++++ Documentation/DocBook/v4l/v4l2.xml | 3 + Documentation/DocBook/v4l/vidioc-dqevent.xml | 124 ++++++++++++++++++++ .../DocBook/v4l/vidioc-subscribe-event.xml | 109 +++++++++++++++++ Documentation/video4linux/v4l2-framework.txt | 43 +++++++ 6 files changed, 322 insertions(+), 0 deletions(-) create mode 100644 Documentation/DocBook/v4l/dev-event.xml create mode 100644 Documentation/DocBook/v4l/vidioc-dqevent.xml create mode 100644 Documentation/DocBook/v4l/vidioc-subscribe-event.xmlDocumentation/DocBook/media-entities.tmpl +9
-0@@ -17,6 +17,7 @@ <!ENTITY VIDIOC-DBG-G-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_G_REGISTER</constant></link>"> <!ENTITY VIDIOC-DBG-S-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_S_REGISTER</constant></link>"> <!ENTITY VIDIOC-DQBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_DQBUF</constant></link>"> +<!ENTITY VIDIOC-DQEVENT "<link linkend='vidioc-dqevent'><constant>VIDIOC_DQEVENT</constant></link>"> <!ENTITY VIDIOC-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_ENCODER_CMD</constant></link>"> <!ENTITY VIDIOC-ENUMAUDIO "<link linkend='vidioc-enumaudio'><constant>VIDIOC_ENUMAUDIO</constant></link>"> <!ENTITY VIDIOC-ENUMAUDOUT "<link linkend='vidioc-enumaudioout'><constant>VIDIOC_ENUMAUDOUT</constant></link>">@@ -60,6 +61,7 @@ <!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>"> <!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>"> <!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>"> +<!ENTITY VIDIOC-SUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_SUBSCRIBE_EVENT</constant></link>"> <!ENTITY VIDIOC-S-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_S_AUDIO</constant></link>"> <!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>"> <!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>">@@ -141,6 +143,8 @@ <!ENTITY v4l2-enc-idx "struct <link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>"> <!ENTITY v4l2-enc-idx-entry "struct <link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>"> <!ENTITY v4l2-encoder-cmd "struct <link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>"> +<!ENTITY v4l2-event "struct <link linkend='v4l2-event'>v4l2_event</link>"> +<!ENTITY v4l2-event-subscription "struct <link linkend='v4l2-event-subscription'>v4l2_event_subscription</link>"> <!ENTITY v4l2-ext-control "struct <link linkend='v4l2-ext-control'>v4l2_ext_control</link>"> <!ENTITY v4l2-ext-controls "struct <link linkend='v4l2-ext-controls'>v4l2_ext_controls</link>"> <!ENTITY v4l2-fmtdesc "struct <link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link>">@@ -200,6 +204,7 @@ <!ENTITY sub-controls SYSTEM "v4l/controls.xml"> <!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml"> <!ENTITY sub-dev-codec SYSTEM "v4l/dev-codec.xml"> +<!ENTITY sub-dev-event SYSTEM "v4l/dev-event.xml"> <!ENTITY sub-dev-effect SYSTEM "v4l/dev-effect.xml"> <!ENTITY sub-dev-osd SYSTEM "v4l/dev-osd.xml"> <!ENTITY sub-dev-output SYSTEM "v4l/dev-output.xml">@@ -292,6 +297,8 @@ <!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml"> <!ENTITY sub-videodev2-h SYSTEM "v4l/videodev2.h.xml"> <!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml"> +<!ENTITY sub-dqevent SYSTEM "v4l/vidioc-dqevent.xml"> +<!ENTITY sub-subscribe-event SYSTEM "v4l/vidioc-subscribe-event.xml"> <!ENTITY sub-intro SYSTEM "dvb/intro.xml"> <!ENTITY sub-frontend SYSTEM "dvb/frontend.xml"> <!ENTITY sub-dvbproperty SYSTEM "dvb/dvbproperty.xml">@@ -381,3 +388,5 @@ <!ENTITY reqbufs SYSTEM "v4l/vidioc-reqbufs.xml"> <!ENTITY s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml"> <!ENTITY streamon SYSTEM "v4l/vidioc-streamon.xml"> +<!ENTITY dqevent SYSTEM "v4l/vidioc-dqevent.xml"> +<!ENTITY subscribe_event SYSTEM "v4l/vidioc-subscribe-event.xml">Documentation/DocBook/v4l/dev-event.xml new file +34
-0@@ -0,0 +1,34 @@ + <title>Event Interface</title> + + <para>The V4L2 event interface provides means for user to get + immediately notified on certain conditions taking place on a device. + This might include start of frame or loss of signal events, for + example. + </para> + + <para>To receive events, the events the user is interested first + must be subscribed using the &VIDIOC-SUBSCRIBE-EVENT; ioctl. Once an + event is subscribed, the events of subscribed types are dequeueable + using the &VIDIOC-DQEVENT; ioctl. Events may be unsubscribed using + VIDIOC_UNSUBSCRIBE_EVENT ioctl. The special event type + V4L2_EVENT_ALL may be used to subscribe or unsubscribe all the + events the driver supports.</para> + + <para>The event subscriptions and event queues are specific to file + handles. Subscribing an event on one file handle does not affect + other file handles. + </para> + + <para>The information on dequeueable events are obtained by using + select or poll system calls on video devices. The V4L2 events use + POLLPRI events on poll system call and exceptions on select system + call. + </para> + + <!-- +Local Variables: +mode: sgml +sgml-parent-document: "v4l2.sgml" +indent-tabs-mode: nil +End: + -->Documentation/DocBook/v4l/v4l2.xml +3
-0@@ -401,6 +401,7 @@ and discussions on the V4L mailing list.</revremark> <section id="ttx"> &sub-dev-teletext; </section> <section id="radio"> &sub-dev-radio; </section> <section id="rds"> &sub-dev-rds; </section> + <section id="event"> &sub-dev-event; </section> </chapter> <chapter id="driver">@@ -426,6 +427,7 @@ and discussions on the V4L mailing list.</revremark> &sub-cropcap; &sub-dbg-g-chip-ident; &sub-dbg-g-register; + &sub-dqevent; &sub-encoder-cmd; &sub-enumaudio; &sub-enumaudioout;@@ -467,6 +469,7 @@ and discussions on the V4L mailing list.</revremark> &sub-reqbufs; &sub-s-hw-freq-seek; &sub-streamon; + &sub-subscribe-event; <!-- End of ioctls. --> &sub-mmap; &sub-munmap;Documentation/DocBook/v4l/vidioc-dqevent.xml new file +124
-0@@ -0,0 +1,124 @@ +<refentry id="vidioc-dqevent"> + <refmeta> + <refentrytitle>ioctl VIDIOC_DQEVENT</refentrytitle> + &manvol; + </refmeta> + + <refnamediv> + <refname>VIDIOC_DQEVENT</refname> + <refpurpose>Dequeue event</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcprototype> + <funcdef>int <function>ioctl</function></funcdef> + <paramdef>int <parameter>fd</parameter></paramdef> + <paramdef>int <parameter>request</parameter></paramdef> + <paramdef>struct v4l2_event +*<parameter>argp</parameter></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1> + <title>Arguments</title> + + <variablelist> + <varlistentry> + <term><parameter>fd</parameter></term> + <listitem> + <para>&fd;</para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>request</parameter></term> + <listitem> + <para>VIDIOC_DQEVENT</para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>argp</parameter></term> + <listitem> + <para></para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Description</title> + + <para>Dequeue an event from a video device. No input is required + for this ioctl. All the fields of the &v4l2-event; structure are + filled by the driver. The file handle will also receive exceptions + which the application may get by e.g. using the select system + call.</para> + + <table frame="none" pgwide="1" id="v4l2-event"> + <title>struct <structname>v4l2_event</structname></title> + <tgroup cols="4"> + &cs-str; + <tbody valign="top"> + <row> + <entry>__u32</entry> + <entry><structfield>type</structfield></entry> + <entry></entry> + <entry>Type of the event.</entry> + </row> + <row> + <entry>union</entry> + <entry><structfield>u</structfield></entry> + <entry></entry> + <entry></entry> + </row> + <row> + <entry></entry> + <entry>__u8</entry> + <entry><structfield>data</structfield>[64]</entry> + <entry>Event data. Defined by the event type. The union + should be used to define easily accessible type for + events.</entry> + </row> + <row> + <entry>__u32</entry> + <entry><structfield>pending</structfield></entry> + <entry></entry> + <entry>Number of pending events excluding this one.</entry> + </row> + <row> + <entry>__u32</entry> + <entry><structfield>sequence</structfield></entry> + <entry></entry> + <entry>Event sequence number. The sequence number is + incremented for every subscribed event that takes place. + If sequence numbers are not contiguous it means that + events have been lost. + </entry> + </row> + <row> + <entry>struct timeval</entry> + <entry><structfield>timestamp</structfield></entry> + <entry></entry> + <entry>Event timestamp.</entry> + </row> + <row> + <entry>__u32</entry> + <entry><structfield>reserved</structfield>[9]</entry> + <entry></entry> + <entry>Reserved for future extensions. Drivers must set + the array to zero.</entry> + </row> + </tbody> + </tgroup> + </table> + + </refsect1> +</refentry> +<!-- +Local Variables: +mode: sgml +sgml-parent-document: "v4l2.sgml" +indent-tabs-mode: nil +End: +-->Documentation/DocBook/v4l/vidioc-subscribe-event.xml new file +43
-0@@ -0,0 +1,109 @@ +<refentry id="vidioc-subscribe-event"> + <refmeta> + <refentrytitle>ioctl VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT</refentrytitle> + &manvol; + </refmeta> + + <refnamediv> + <refname>VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT</refname> + <refpurpose>Subscribe or unsubscribe event</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcprototype> + <funcdef>int <function>ioctl</function></funcdef> + <paramdef>int <parameter>fd</parameter></paramdef> + <paramdef>int <parameter>request</parameter></paramdef> + <paramdef>struct v4l2_event_subscription +*<parameter>argp</parameter></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1> + <title>Arguments</title> + + <variablelist> + <varlistentry> + <term><parameter>fd</parameter></term> + <listitem> + <para>&fd;</para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>request</parameter></term> + <listitem> + <para>VIDIOC_SUBSCRIBE_EVENT, VIDIOC_UNSUBSCRIBE_EVENT</para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>argp</parameter></term> + <listitem> + <para></para>
Documentation/DocBook/v4l/vidioc-subscribe-event.xml line 53
Quoted 10 lines
Documentation/DocBook/v4l/vidioc-subscribe-event.xml new file +10
-0+ </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Description</title> + + <para>Subscribe or unsubscribe V4L2 event. Subscribed events are + dequeued by using the &VIDIOC-SUBSCRIBE-EVENT; ioctl.</para>
You mean VIDIOC-DQUEUE, I assume.
Documentation/DocBook/v4l/vidioc-subscribe-event.xml line 56
Quoted 3 lines
Documentation/DocBook/v4l/vidioc-subscribe-event.xml new file +3
-0+ + There are standard and private events. New standard events must + use the smallest available event type.
That last sentence belongs in v4l2-framework.txt, not here.
Quoted 29 lines
Documentation/DocBook/v4l/vidioc-subscribe-event.xml new file +29
-0+ + <table frame="none" pgwide="1" id="v4l2-event-subscription"> + <title>struct <structname>v4l2_event_subscription</structname></title> + <tgroup cols="3"> + &cs-str; + <tbody valign="top"> + <row> + <entry>__u32</entry> + <entry><structfield>type</structfield></entry> + <entry>Type of the event.</entry> + </row> + <row> + <entry>__u32</entry> + <entry><structfield>reserved</structfield>[7]</entry> + <entry>Reserved for future extensions. Drivers must set + the array to zero.</entry> + </row> + </tbody> + </tgroup> + </table> + + <table frame="none" pgwide="1" id="event-type"> + <title>Event Types</title> + <tgroup cols="3"> + &cs-def; + <tbody valign="top"> + <row> + <entry><constant>V4L2_EVENT_ALL</constant></entry> + <entry>0</entry>
Documentation/DocBook/v4l/vidioc-subscribe-event.xml line 95
Quoted 10 lines
Documentation/DocBook/v4l/vidioc-subscribe-event.xml new file +10
-0+ <entry>All events. The user may subscribe + for all events supported by the driver by subscribing a + special event, V4L2_EVENT_ALL.</entry> + </row> + <row> + <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry> + <entry>0x08000000</entry> <entry>Private events start from + this number. The drivers must allocate their events + starting from base (V4L2_EVENT_PRIVATE_START + n * 1024) + where individual events start from base + 1.</entry>
Again, that last sentence belongs in v4l2-framework.txt.
Quoted 19 lines
Documentation/DocBook/v4l/vidioc-subscribe-event.xml new file +14
-0+ </row> + </tbody> + </tgroup> + </table> + + </refsect1> +</refentry> +<!-- +Local Variables: +mode: sgml +sgml-parent-document: "v4l2.sgml" +indent-tabs-mode: nil +End: +-->Documentation/video4linux/v4l2-framework.txt +0
-0
Documentation/video4linux/v4l2-framework.txt Useful functions: · line 740
Quoted 10 lines
Documentation/video4linux/v4l2-framework.txt +7
-0@@ -731,3 +731,46 @@ Useful functions: The users of v4l2_fh know whether a driver uses v4l2_fh as its file.private_data pointer by testing the V4L2_FL_USES_V4L2_FH bit in video_device.flags. + +V4L2 events +----------- + +The V4L2 events provide a generic way to pass events to user space. +The driver must use v4l2_fh to be able to support V4L2 events. To +support V4L2 events, the driver must
Must what?
Documentation/video4linux/v4l2-framework.txt Useful functions: · line 749
Quoted 9 lines
Documentation/video4linux/v4l2-framework.txt +9
-0+ +- v4l2_event_alloc() + + To use events, the driver must allocate events for the file handle. By + calling the function more than once, the driver may assure that at least n + events in total has been allocated. The function may not be called in + atomic context. If the driver only wants to initialise events it is fine + to call v4l2_event_alloc() with 0 allocation. This allows passing the + ioctls to the driver.
This is unnecessarily complex. And based on my comments on the previous patches it is also not needed. Drivers can call v4l2_event_alloc either after calling v4l2_fh_init or in the subscribe_event op.
Documentation/video4linux/v4l2-framework.txt Useful functions: · line 758
Quoted 9 lines
Documentation/video4linux/v4l2-framework.txt +9
-0+ +- v4l2_event_queue() + + Queue events to video device. The driver's only responsibility is to fill + in the type and the data fields. The other fields will be filled in by + V4L2. + +- Define vidioc_subscribe_event in struct v4l2_ioctl_ops. The + vidioc_subscribe_event must chech the driver is able to produce events
typo: check
Documentation/video4linux/v4l2-framework.txt Useful functions: · line 769
Quoted 11 lines
Documentation/video4linux/v4l2-framework.txt +11
-0+ with specified event id. Then it calls v4l2_event_subscribe() to subscribe + the event. + +- Define vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use + v4l2_event_unsubscribe directly unless it wants to be involved in + unsubscription process. + +- To support V4L2_EVENTS_ALL, the driver must handle the special id + V4L2_EVENTS_ALL when subscribing for events. The function + v4l2_event_subscribe_many() is useful in implementing this. Unsubscription + of all events is already handled by vidioc_unsubscribe_event().
This should only be supported by unsubscribe.
Documentation/video4linux/v4l2-framework.txt Useful functions: · line 772
Quoted 3 lines
Documentation/video4linux/v4l2-framework.txt +3
-0+ +- Events are delivered to user space through the poll system call. The + driver should use a separate wait queue for the V4L2 events.
I don't quite get what you mean by this. I am also missing a reference to the fh->events->wait queue. That's a rather important piece of information to document.
You should also document v4l2_event_pending and mention that dequeuing is done internally through the v4l2_event_dequeue call that needs no driver support.
Regards,
Hans
Quoted 5 lines
Documentation/video4linux/v4l2-framework.txt +4
-0+ +An example on how the V4L2 events may be used can be found in the OMAP +3 ISP driver available at <URL:http://gitorious.org/omap3camera> as of +writing this.
Signature · 1 line
Hans Verkuil - video4linux developer - sponsored by TANDBERG