From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kay Sievers Date: Wed, 08 Aug 2007 10:48:59 +0000 Subject: Re: work-around for video4linux sysfs Message-Id: <1186570139.2573.5.camel@lov.localdomain> MIME-Version: 1 Content-Type: multipart/mixed; boundary="=-6tLbplqrDDm4UqPP31ry" List-Id: References: <20070731195136.GW9881@outflux.net> In-Reply-To: <20070731195136.GW9881@outflux.net> To: linux-hotplug@vger.kernel.org --=-6tLbplqrDDm4UqPP31ry Content-Type: text/plain Content-Transfer-Encoding: 7bit On Tue, 2007-08-07 at 16:18 -0700, Kees Cook wrote: > On Wed, Aug 08, 2007 at 12:58:43AM +0200, Kay Sievers wrote: > > Look at drivers/media/video/videodev.c how the "name" attribute is > > created. There should probably be common "function" names added to > > the v4l core which are just referenced by the drivers, like the > > defines for the device type in include/media/v4l2-dev.h which are > > replaced by strings in drivers/media/video/videodev.c. > > Okay, thanks. I'll try to find some time to investigate this. Try the attached patch as a start. It adds a "function" attribute to every v4l device. You need to add the classification to the drivers you use, to see if that will work for you. I added V4L2_FN_VIDEO_CAP to my ancient webcam: $ grep . /sys/class/video4linux/*/* /sys/class/video4linux/video0/bridge:OV511+ /sys/class/video4linux/video0/brightness:126 /sys/class/video4linux/video0/contrast:86 /sys/class/video4linux/video0/custom_id:21 /sys/class/video4linux/video0/dev:81:0 /sys/class/video4linux/video0/exposure:0 /sys/class/video4linux/video0/function:video-cap /sys/class/video4linux/video0/hue:128 /sys/class/video4linux/video0/model:Creative Labs WebCam 3 /sys/class/video4linux/video0/name:OV511 USB Camera /sys/class/video4linux/video0/saturation:192 /sys/class/video4linux/video0/sensor:OV7620 Good luck, Kay --=-6tLbplqrDDm4UqPP31ry Content-Disposition: inline; filename=v4l-function-attr.patch Content-Type: text/x-patch; name=v4l-function-attr.patch; charset=utf-8 Content-Transfer-Encoding: 7bit diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index e5edff1..511d094 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -4668,6 +4668,7 @@ static struct video_device vdev_template = { .owner = THIS_MODULE, .name = "OV511 USB Camera", .type = VID_TYPE_CAPTURE, + .function = V4L2_FN_VIDEO_CAP, .hardware = VID_HARDWARE_OV511, .fops = &ov511_fops, .release = video_device_release, diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index d2915d3..84ded35 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -247,6 +247,45 @@ int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local) return 0; } +/* + * Exports "function" string to userspace to identify the type of device + * if multiple streams are available for a single device. + * + * Types/string names should be reused if possible, instead of adding + * new very device specific types, they must _uniquely_ identify all + * streams belonging to the _same_ device though. + * + * No single device must export multiple streams with the same function + * string, because userspace this to find the correct device node. + * + * Unlike the free-text "name", it must be an easily machine useable + * string containing only [a-z0-9._-] characters. + * + * Strings must not change without a valid reason, they are part of the + * sysfs ABI. + * + */ +static const char *v4l2_function_type_names[] = { + [V4L2_FN_UNDEFINED] = "undefined", + [V4L2_FN_VIDEO_CAP] = "video-cap", + [V4L2_FN_VIDEO_OUT] = "video-out", + [V4L2_FN_MPEG_CAP] = "mpeg-cap", + [V4L2_FN_MPEG_OUT] = "mpeg-out", + [V4L2_FN_YUV_CAP] = "yuv-cap", + [V4L2_FN_YUV_OUT] = "yuv-out", + [V4L2_FN_VBI_CAP] = "vbi-cap", + [V4L2_FN_VBI_OUT] = "vbi-out", + [V4L2_FN_PCM_CAP] = "pcm-cap", + [V4L2_FN_PCM_OUT] = "pcm-out", +}; + +const char *v4l2_function_name(enum v4l2_function_type function) +{ + if (function >= 0 && function < ARRAY_SIZE(v4l2_function_type_names)) + return v4l2_function_type_names[function]; + printk(KERN_ERR "v4ls: unknown v4l2_function_type\n"); + return "error"; +} /* ----------------------------------------------------------------- */ /* some arrays for pretty-printing debug messages of enum types */ diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index b876aca..582773c 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -61,7 +61,12 @@ static ssize_t show_name(struct class_device *cd, char *buf) return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name); } -static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL); +static ssize_t show_function(struct class_device *cd, char *buf) +{ + struct video_device *vfd = container_of(cd, struct video_device, + class_dev); + return sprintf(buf, "%s\n", v4l2_function_name(vfd->function)); +} struct video_device *video_device_alloc(void) { @@ -89,8 +94,15 @@ static void video_release(struct class_device *cd) vfd->release(vfd); } +static struct class_device_attribute video_device_attrs[] = { + __ATTR(name, S_IRUGO, show_name, NULL), + __ATTR(function, S_IRUGO, show_function, NULL), + __ATTR_NULL +}; + static struct class video_class = { .name = VIDEO_NAME, + .class_dev_attrs = video_device_attrs, .release = video_release, }; @@ -1763,12 +1775,6 @@ int video_register_device(struct video_device *vfd, int type, int nr) __FUNCTION__); goto fail_minor; } - ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name); - if (ret < 0) { - printk(KERN_ERR "%s: class_device_create_file 'name' failed\n", - __FUNCTION__); - goto fail_classdev; - } #if 1 /* needed until all drivers are fixed */ @@ -1779,8 +1785,6 @@ int video_register_device(struct video_device *vfd, int type, int nr) #endif return 0; -fail_classdev: - class_device_unregister(&vfd->class_dev); fail_minor: mutex_lock(&videodev_lock); video_device[vfd->minor] = NULL; diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index c66c8a3..d048d46 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -138,6 +138,23 @@ enum v4l2_field { (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) +/* Exports "function" string to userspace to identify type of device */ +enum v4l2_function_type { + V4L2_FN_UNDEFINED, + V4L2_FN_VIDEO_CAP, + V4L2_FN_VIDEO_OUT, + V4L2_FN_MPEG_CAP, + V4L2_FN_MPEG_OUT, + V4L2_FN_YUV_CAP, + V4L2_FN_YUV_OUT, + V4L2_FN_VBI_CAP, + V4L2_FN_VBI_OUT, + V4L2_FN_PCM_CAP, + V4L2_FN_PCM_OUT, +}; + +extern const char *v4l2_function_name(enum v4l2_function_type function); + enum v4l2_buf_type { V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index d62847f..0141b6c 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -93,6 +93,7 @@ struct video_device char name[32]; int type; /* v4l1 */ int type2; /* v4l2 */ + enum v4l2_function_type function; /* sysfs string */ int hardware; int minor; --=-6tLbplqrDDm4UqPP31ry Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ --=-6tLbplqrDDm4UqPP31ry Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net Linux-hotplug-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel --=-6tLbplqrDDm4UqPP31ry--