ivtv: fix incorrect device_caps for ivtvfb
authorHans Verkuil <hverkuil-cisco@xs4all.nl>
Sun, 6 Mar 2022 11:29:11 +0000 (12:29 +0100)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Mon, 7 Mar 2022 16:21:53 +0000 (17:21 +0100)
The VIDIOC_G_FBUF and related overlay ioctls no longer worked (-ENOTTY was
returned).

The root cause was the introduction of the caps field in ivtv-driver.h.
While loading the ivtvfb module would update the video_device device_caps
field with V4L2_CAP_VIDEO_OUTPUT_OVERLAY it would not update that caps
field, and that's what the overlay ioctls would look at.

It's a bad idea to keep information in two places, so drop the caps field
and only use vdev.device_caps.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Reported-by: Martin Dauskardt <martin.dauskardt@gmx.de>
Fixes: 2161536516ed (media: media/pci: set device_caps in struct video_device)

drivers/media/pci/ivtv/ivtv-driver.h
drivers/media/pci/ivtv/ivtv-ioctl.c
drivers/media/pci/ivtv/ivtv-streams.c

index 4cf92de..ce3a7ca 100644 (file)
@@ -330,7 +330,6 @@ struct ivtv_stream {
        struct ivtv *itv;               /* for ease of use */
        const char *name;               /* name of the stream */
        int type;                       /* stream type */
-       u32 caps;                       /* V4L2 capabilities */
 
        struct v4l2_fh *fh;             /* pointer to the streaming filehandle */
        spinlock_t qlock;               /* locks access to the queues */
index 0cdf6b3..fee460e 100644 (file)
@@ -438,7 +438,7 @@ static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_f
        struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
        struct v4l2_window *winfmt = &fmt->fmt.win;
 
-       if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+       if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
                return -EINVAL;
        if (!itv->osd_video_pbase)
                return -EINVAL;
@@ -549,7 +549,7 @@ static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2
        u32 chromakey = fmt->fmt.win.chromakey;
        u8 global_alpha = fmt->fmt.win.global_alpha;
 
-       if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+       if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
                return -EINVAL;
        if (!itv->osd_video_pbase)
                return -EINVAL;
@@ -1383,7 +1383,7 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
                0,
        };
 
-       if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+       if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
                return -ENOTTY;
        if (!itv->osd_video_pbase)
                return -ENOTTY;
@@ -1450,7 +1450,7 @@ static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffe
        struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
        struct yuv_playback_info *yi = &itv->yuv_info;
 
-       if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+       if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
                return -ENOTTY;
        if (!itv->osd_video_pbase)
                return -ENOTTY;
@@ -1470,7 +1470,7 @@ static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
        struct ivtv *itv = id->itv;
        struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
 
-       if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+       if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
                return -ENOTTY;
        if (!itv->osd_video_pbase)
                return -ENOTTY;
index 6e45594..13d7d55 100644 (file)
@@ -176,7 +176,7 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
        s->itv = itv;
        s->type = type;
        s->name = ivtv_stream_info[type].name;
-       s->caps = ivtv_stream_info[type].v4l2_caps;
+       s->vdev.device_caps = ivtv_stream_info[type].v4l2_caps;
 
        if (ivtv_stream_info[type].pio)
                s->dma = DMA_NONE;
@@ -299,12 +299,9 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
                if (s_mpg->vdev.v4l2_dev)
                        num = s_mpg->vdev.num + ivtv_stream_info[type].num_offset;
        }
-       s->vdev.device_caps = s->caps;
-       if (itv->osd_video_pbase) {
-               itv->streams[IVTV_DEC_STREAM_TYPE_YUV].vdev.device_caps |=
-                       V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
-               itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps |=
-                       V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
+       if (itv->osd_video_pbase && (type == IVTV_DEC_STREAM_TYPE_YUV ||
+                                    type == IVTV_DEC_STREAM_TYPE_MPG)) {
+               s->vdev.device_caps |= V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
                itv->v4l2_cap |= V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
        }
        video_set_drvdata(&s->vdev, s);