@@ -1956,6 +1956,7 @@ static void uvc_unregister_video(struct uvc_device *dev)
int uvc_register_video_device(struct uvc_device *dev,
struct uvc_streaming *stream,
+ unsigned int inst,
struct video_device *vdev,
struct uvc_video_queue *queue,
enum v4l2_buf_type type,
@@ -1990,17 +1991,18 @@ int uvc_register_video_device(struct uvc_device *dev,
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
default:
vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ snprintf(vdev->name, sizeof(vdev->name), "Cap%u %s", inst, dev->name);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+ snprintf(vdev->name, sizeof(vdev->name), "Out%u %s", inst, dev->name);
break;
case V4L2_BUF_TYPE_META_CAPTURE:
vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
+ snprintf(vdev->name, sizeof(vdev->name), "Meta%u %s", inst, dev->name);
break;
}
- strscpy(vdev->name, dev->name, sizeof(vdev->name));
-
/*
* Set the driver data before calling video_register_device, otherwise
* the file open() handler might race us.
@@ -2020,7 +2022,7 @@ int uvc_register_video_device(struct uvc_device *dev,
}
static int uvc_register_video(struct uvc_device *dev,
- struct uvc_streaming *stream)
+ struct uvc_streaming *stream, unsigned int inst)
{
int ret;
@@ -2041,7 +2043,7 @@ static int uvc_register_video(struct uvc_device *dev,
uvc_debugfs_init_stream(stream);
/* Register the device with V4L. */
- return uvc_register_video_device(dev, stream, &stream->vdev,
+ return uvc_register_video_device(dev, stream, inst, &stream->vdev,
&stream->queue, stream->type,
&uvc_fops, &uvc_ioctl_ops);
}
@@ -2054,9 +2056,13 @@ static int uvc_register_terms(struct uvc_device *dev,
{
struct uvc_streaming *stream;
struct uvc_entity *term;
+ unsigned int inst_cap = 0;
+ unsigned int inst_out = 0;
int ret;
list_for_each_entry(term, &chain->entities, chain) {
+ bool is_capture;
+
if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
continue;
@@ -2069,16 +2075,22 @@ static int uvc_register_terms(struct uvc_device *dev,
}
stream->chain = chain;
- ret = uvc_register_video(dev, stream);
+ is_capture = stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ ret = uvc_register_video(dev, stream,
+ is_capture ? inst_cap : inst_out);
if (ret < 0)
return ret;
- /*
- * Register a metadata node, but ignore a possible failure,
- * complete registration of video nodes anyway.
- */
- uvc_meta_register(stream);
-
+ if (is_capture) {
+ /*
+ * Register a metadata node, but ignore a possible failure,
+ * complete registration of video nodes anyway.
+ */
+ uvc_meta_register(stream, inst_cap);
+ inst_cap++;
+ } else {
+ inst_out++;
+ }
term->vdev = &stream->vdev;
}
@@ -156,7 +156,7 @@ static const struct v4l2_file_operations uvc_meta_fops = {
.mmap = vb2_fop_mmap,
};
-int uvc_meta_register(struct uvc_streaming *stream)
+int uvc_meta_register(struct uvc_streaming *stream, unsigned int inst)
{
struct uvc_device *dev = stream->dev;
struct video_device *vdev = &stream->meta.vdev;
@@ -170,7 +170,7 @@ int uvc_meta_register(struct uvc_streaming *stream)
*/
vdev->queue = &queue->queue;
- return uvc_register_video_device(dev, stream, vdev, queue,
+ return uvc_register_video_device(dev, stream, inst, vdev, queue,
V4L2_BUF_TYPE_META_CAPTURE,
&uvc_meta_fops, &uvc_meta_ioctl_ops);
}
@@ -738,10 +738,11 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit,
void uvc_video_clock_update(struct uvc_streaming *stream,
struct vb2_v4l2_buffer *vbuf,
struct uvc_buffer *buf);
-int uvc_meta_register(struct uvc_streaming *stream);
+int uvc_meta_register(struct uvc_streaming *stream, unsigned int inst);
int uvc_register_video_device(struct uvc_device *dev,
struct uvc_streaming *stream,
+ unsigned int inst,
struct video_device *vdev,
struct uvc_video_queue *queue,
enum v4l2_buf_type type,
The video device names (also used as entity names) are identical for the video capture and metadata capture devices. This series ensures that the video device names are unique. It also fixes a bug where a metadata device would be created for video output devices, but that's for video capture devices only. This fixes a compliance failure when running 'v4l2-compliance -M /dev/mediaX'. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> --- RFC for now. Based on the code I assume one UVC device can have multiple capture and/or output devices, so I added an instance index. But I may be wrong about that. I also assume that there is no metadata for UVC video outputs. It might also be safer to drop the 'Cap0 ' prefix if inst == 0, just in case someone relies on the name. --- drivers/media/usb/uvc/uvc_driver.c | 34 +++++++++++++++++++--------- drivers/media/usb/uvc/uvc_metadata.c | 4 ++-- drivers/media/usb/uvc/uvcvideo.h | 3 ++- 3 files changed, 27 insertions(+), 14 deletions(-)