v4l2-compliance: test for ENOTTY compliance.
authorHans Verkuil <hans.verkuil@cisco.com>
Fri, 29 Jul 2011 13:02:38 +0000 (15:02 +0200)
committerHans Verkuil <hans.verkuil@cisco.com>
Fri, 29 Jul 2011 13:02:38 +0000 (15:02 +0200)
Unsupported ioctls used to return -EINVAL, but now they return -ENOTTY.

This patch changes the compliance tests to take this into account.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
utils/v4l2-compliance/v4l2-compliance.cpp
utils/v4l2-compliance/v4l2-test-controls.cpp
utils/v4l2-compliance/v4l2-test-debug.cpp
utils/v4l2-compliance/v4l2-test-formats.cpp
utils/v4l2-compliance/v4l2-test-input-output.cpp
utils/v4l2-compliance/v4l2-test-io-config.cpp

index f865a76..7704364 100644 (file)
@@ -193,7 +193,7 @@ const char *ok(int res)
 {
        static char buf[100];
 
-       if (res == -ENOSYS) {
+       if (res == ENOTTY) {
                strcpy(buf, "Not Supported");
                res = 0;
        } else {
@@ -248,6 +248,7 @@ static int testCap(struct node *node)
                fail_on_test(vcap.bus_info[0]);
                warn("VIDIOC_QUERYCAP: empty bus_info\n");
        }
+       fail_on_test((vcap.version >> 16) < 3);
        fail_on_test(check_0(vcap.reserved, sizeof(vcap.reserved)));
        caps = vcap.capabilities;
        fail_on_test(vcap.capabilities == 0);
index 5f1b5a0..4a0712d 100644 (file)
@@ -188,6 +188,8 @@ int testQueryControls(struct node *node)
                memset(&qctrl, 0xff, sizeof(qctrl));
                qctrl.id = id | V4L2_CTRL_FLAG_NEXT_CTRL;
                ret = doioctl(node, VIDIOC_QUERYCTRL, &qctrl);
+               if (ret == ENOTTY)
+                       return ret;
                if (ret && ret != EINVAL)
                        return fail("invalid queryctrl return code\n");
                if (ret)
@@ -493,12 +495,10 @@ int testExtendedControls(struct node *node)
 
        memset(&ctrls, 0, sizeof(ctrls));
        ret = doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls);
-       if (ret && !node->controls.empty())
-               return fail("g_ext_ctrls does not support count == 0\n");
-       if (ret && ret != EINVAL)
-               return fail("g_ext_ctrls with count == 0 did not return EINVAL\n");
+       if (ret == ENOTTY && node->controls.empty())
+               return ret;
        if (ret)
-               return -ENOSYS;
+               return fail("g_ext_ctrls does not support count == 0\n");
        if (node->controls.empty())
                return fail("g_ext_ctrls worked even when no controls are present\n");
        if (ctrls.ctrl_class)
index d624e81..074b975 100644 (file)
@@ -61,7 +61,7 @@ int testChipIdent(struct node *node)
                fail_on_test(memcmp(&orig, &chip, sizeof(chip)));
                return 0;
        }
-       return ret == EINVAL ? -ENOSYS : ret;
+       return ret;
 }
 
 int testRegister(struct node *node)
@@ -75,8 +75,8 @@ int testRegister(struct node *node)
        reg.match.addr = 0;
        reg.reg = 0;
        ret = doioctl(node, VIDIOC_DBG_G_REGISTER, &reg);
-       if (ret == EINVAL)
-               return -ENOSYS;
+       if (ret == ENOTTY)
+               return ret;
        // Not allowed to call VIDIOC_DBG_G_REGISTER unless root
        fail_on_test(uid && ret != EPERM);
        fail_on_test(uid == 0 && ret);
@@ -88,14 +88,12 @@ int testRegister(struct node *node)
                // messing with registers in the compliance test.
                reg.reg = reg.val = 0;
                ret = doioctl(node, VIDIOC_DBG_S_REGISTER, &reg);
-               fail_on_test(ret != EINVAL && ret != EPERM);
+               fail_on_test(ret != ENOTTY && ret != EINVAL && ret != EPERM);
        }
        return 0;
 }
 
 int testLogStatus(struct node *node)
 {
-       int ret = doioctl(node, VIDIOC_LOG_STATUS, NULL);
-
-       return (ret == EINVAL) ? -ENOSYS : ret;
+       return doioctl(node, VIDIOC_LOG_STATUS, NULL);
 }
index db9245c..5b56a65 100644 (file)
@@ -63,10 +63,12 @@ static int testEnumFrameIntervals(struct node *node, __u32 pixfmt, __u32 w, __u3
                frmival.height = h;
 
                ret = doioctl(node, VIDIOC_ENUM_FRAMEINTERVALS, &frmival);
+               if (ret == ENOTTY)
+                       return ret;
                if (f == 0 && ret == EINVAL) {
                        if (valid)
                                warn("found framesize %dx%d, but no frame intervals\n", w, h);
-                       return -ENOSYS;
+                       return ENOTTY;
                }
                if (ret == EINVAL)
                        break;
@@ -130,8 +132,10 @@ static int testEnumFrameSizes(struct node *node, __u32 pixfmt)
                frmsize.pixel_format = pixfmt;
 
                ret = doioctl(node, VIDIOC_ENUM_FRAMESIZES, &frmsize);
+               if (ret == ENOTTY)
+                       return ret;
                if (f == 0 && ret == EINVAL)
-                       return -ENOSYS;
+                       return fail("got EINVAL enumerating first framesize\n");
                if (ret == EINVAL)
                        break;
                if (ret)
@@ -149,11 +153,11 @@ static int testEnumFrameSizes(struct node *node, __u32 pixfmt)
                                return fail("mixing discrete and stepwise is not allowed\n");
                        ret = testEnumFrameIntervals(node, pixfmt,
                                        frmsize.discrete.width, frmsize.discrete.height, true);
-                       if (ret > 0)
+                       if (ret && ret != ENOTTY)
                                return ret;
                        ret = testEnumFrameIntervals(node, pixfmt,
                                        frmsize.discrete.width + 1, frmsize.discrete.height, false);
-                       if (ret > 0)
+                       if (ret && ret != ENOTTY)
                                return ret;
                        break;
                case V4L2_FRMSIZE_TYPE_CONTINUOUS:
@@ -173,19 +177,19 @@ static int testEnumFrameSizes(struct node *node, __u32 pixfmt)
                                return fail("step > max - min for width or height\n");
                        ret = testEnumFrameIntervals(node, pixfmt,
                                        sw->min_width, sw->min_height, true);
-                       if (ret > 0)
+                       if (ret && ret != ENOTTY)
                                return ret;
                        ret = testEnumFrameIntervals(node, pixfmt,
                                        sw->max_width, sw->max_height, true);
-                       if (ret > 0)
+                       if (ret && ret != ENOTTY)
                                return ret;
                        ret = testEnumFrameIntervals(node, pixfmt,
                                        sw->min_width - 1, sw->min_height, false);
-                       if (ret > 0)
+                       if (ret && ret != ENOTTY)
                                return ret;
                        ret = testEnumFrameIntervals(node, pixfmt,
                                        sw->max_width, sw->max_height + 1, false);
-                       if (ret > 0)
+                       if (ret && ret != ENOTTY)
                                return ret;
                        break;
                default:
@@ -211,8 +215,10 @@ static int testEnumFormatsType(struct node *node, enum v4l2_buf_type type)
                fmtdesc.index = f;
 
                ret = doioctl(node, VIDIOC_ENUM_FMT, &fmtdesc);
+               if (ret == ENOTTY)
+                       return ret;
                if (f == 0 && ret == EINVAL)
-                       return -ENOSYS;
+                       return ENOTTY;
                if (ret == EINVAL)
                        break;
                if (ret)
@@ -234,7 +240,7 @@ static int testEnumFormatsType(struct node *node, enum v4l2_buf_type type)
                if (fmtdesc.flags & ~(V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_EMULATED))
                        return fail("unknown flag %08x returned\n", fmtdesc.flags);
                ret = testEnumFrameSizes(node, fmtdesc.pixelformat);
-               if (ret > 0)
+               if (ret && ret != ENOTTY)
                        return ret;
                if (ret == 0 && !(node->caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)))
                        return fail("found framesizes when no video capture is supported\n");
@@ -271,7 +277,7 @@ int testEnumFormats(struct node *node)
 
        for (type = 0; type <= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; type++) {
                ret = testEnumFormatsType(node, (enum v4l2_buf_type)type);
-               if (ret > 0)
+               if (ret && ret != ENOTTY)
                        return ret;
                switch (type) {
                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -279,7 +285,7 @@ int testEnumFormats(struct node *node)
                case V4L2_BUF_TYPE_VIDEO_OVERLAY:
                case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
                case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-                       if (ret < 0 && (node->caps & buftype2cap[type]))
+                       if (ret && (node->caps & buftype2cap[type]))
                                return fail("%s cap set, but no %s formats defined\n",
                                                buftype2s(type).c_str(), buftype2s(type).c_str());
                        if (!ret && !(node->caps & buftype2cap[type]))
@@ -294,16 +300,16 @@ int testEnumFormats(struct node *node)
        }
 
        ret = testEnumFormatsType(node, V4L2_BUF_TYPE_PRIVATE);
-       if (ret > 0)
+       if (ret && ret != ENOTTY)
                return ret;
        if (!ret)
                warn("Buffer type PRIVATE allowed!\n");
                
        ret = testEnumFrameSizes(node, 0x20202020);
-       if (ret >= 0)
+       if (ret != ENOTTY)
                return fail("Accepted framesize for invalid format\n");
        ret = testEnumFrameIntervals(node, 0x20202020, 640, 480, false);
-       if (ret >= 0)
+       if (ret != ENOTTY)
                return fail("Accepted frameinterval for invalid format\n");
        return 0;
 }
@@ -320,10 +326,10 @@ int testFBuf(struct node *node)
        fbuf.fmt.priv = 0;
        ret = doioctl(node, VIDIOC_G_FBUF, &fbuf);
        fail_on_test(ret == 0 && !(node->caps & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)));
-       fail_on_test(ret == EINVAL && (node->caps & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)));
-       if (ret == EINVAL)
-               return -ENOSYS;
-       if (ret)
+       fail_on_test(ret == ENOTTY && (node->caps & (V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)));
+       if (ret == ENOTTY)
+               return ret;
+       if (ret != EINVAL)
                return fail("expected EINVAL, but got %d when getting framebuffer format\n", ret);
        node->fbuf_caps = caps = fbuf.capability;
        flags = fbuf.flags;
@@ -371,11 +377,15 @@ static int testFormatsType(struct node *node, enum v4l2_buf_type type)
        memset(&fmt, 0xff, sizeof(fmt));
        fmt.type = type;
        ret = doioctl(node, VIDIOC_G_FMT, &fmt);
+       if (ret == ENOTTY)
+               return ret;
        if (ret == EINVAL)
-               return -ENOSYS;
+               return ENOTTY;
        if (ret)
                return fail("expected EINVAL, but got %d when getting format for buftype %d\n", ret, type);
        fail_on_test(fmt.type != type);
+       if (ret)
+               return 0;
        
        switch (type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -474,7 +484,7 @@ int testFormats(struct node *node)
        for (type = 0; type <= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; type++) {
                ret = testFormatsType(node, (enum v4l2_buf_type)type);
 
-               if (ret > 0)
+               if (ret && ret != ENOTTY)
                        return ret;
                if (ret && (node->caps & buftype2cap[type]))
                        return fail("%s cap set, but no %s formats defined\n",
@@ -485,7 +495,7 @@ int testFormats(struct node *node)
        }
 
        ret = testFormatsType(node, V4L2_BUF_TYPE_PRIVATE);
-       if (ret > 0)
+       if (ret && ret != ENOTTY)
                return ret;
        if (!ret)
                warn("Buffer type PRIVATE allowed!\n");
@@ -504,18 +514,17 @@ static int testSlicedVBICapType(struct node *node, enum v4l2_buf_type type)
        memset(&cap.reserved, 0, sizeof(cap.reserved));
        cap.type = type;
        ret = doioctl(node, VIDIOC_G_SLICED_VBI_CAP, &cap);
-       fail_on_test(check_0(cap.reserved, sizeof(cap.reserved)));
-       fail_on_test(cap.type != type);
-       fail_on_test(ret && ret != EINVAL && sliced_type);
-       if (ret == EINVAL) {
+       if (ret == ENOTTY) {
                fail_on_test(sliced_type && (node->caps & buftype2cap[type]));
-               if (node->caps & (V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT))
-                       return 0;
-               return -ENOSYS;
+               return ret;
        }
+       fail_on_test(check_0(cap.reserved, sizeof(cap.reserved)));
+       fail_on_test(cap.type != type);
+       fail_on_test(ret && ret != EINVAL);
+       fail_on_test(ret && sliced_type && (node->caps & buftype2cap[type]));
+       fail_on_test(!ret && (!sliced_type || !(node->caps & buftype2cap[type])));
        if (ret)
-               return fail("expected EINVAL, but got %d when getting sliced VBI caps buftype %d\n", ret, type);
-       fail_on_test(!(node->caps & buftype2cap[type]));
+               return 0;
 
        for (int f = 0; f < 2; f++)
                for (int i = 0; i < 24; i++)
index 31364fd..44d2253 100644 (file)
@@ -125,8 +125,8 @@ int testTuner(struct node *node)
                memset(tuner.reserved, 0, sizeof(tuner.reserved));
                tuner.index = t;
                ret = doioctl(node, VIDIOC_G_TUNER, &tuner);
-               if (ret == EINVAL && t == 0)
-                       return -ENOSYS;
+               if (ret == ENOTTY)
+                       return ret;
                if (ret == EINVAL)
                        break;
                if (ret)
@@ -224,16 +224,16 @@ int testTunerFreq(struct node *node)
 
        freq.tuner = t;
        ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
-       if (ret != EINVAL)
+       if (ret != EINVAL && ret != ENOTTY)
                return fail("could get frequency for invalid tuner %d\n", t);
        freq.tuner = t;
        freq.type = last_type;
        // TV: 400 Mhz Radio: 100 MHz
        freq.frequency = last_type == V4L2_TUNER_ANALOG_TV ? 6400 : 1600000;
        ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
-       if (ret != EINVAL)
+       if (ret != EINVAL && ret != ENOTTY)
                return fail("could set frequency for invalid tuner %d\n", t);
-       return node->tuners ? 0 : -ENOSYS;
+       return node->tuners ? 0 : ENOTTY;
 }
 
 static int checkInput(struct node *node, const struct v4l2_input &descr, unsigned i)
@@ -275,16 +275,16 @@ int testInput(struct node *node)
        int ret = doioctl(node, VIDIOC_G_INPUT, &cur_input);
        int i = 0;
 
-       if (ret == EINVAL) {
+       if (ret == ENOTTY) {
                descr.index = 0;
                ret = doioctl(node, VIDIOC_ENUMINPUT, &descr);
-               if (ret != EINVAL)
+               if (ret != ENOTTY)
                        return fail("G_INPUT not supported, but ENUMINPUT is\n");
                cur_input = 0;
                ret = doioctl(node, VIDIOC_S_INPUT, &cur_input);
-               if (ret != EINVAL)
+               if (ret != ENOTTY)
                        return fail("G_INPUT not supported, but S_INPUT is\n");
-               return -ENOSYS;
+               return ENOTTY;
        }
        if (ret)
                return fail("could not get current input\n");
@@ -350,8 +350,8 @@ int testEnumInputAudio(struct node *node)
                input.index = i;
 
                ret = doioctl(node, VIDIOC_ENUMAUDIO, &input);
-               if (i == 0 && ret == EINVAL)
-                       return -ENOSYS;
+               if (ret == ENOTTY)
+                       return ret;
                if (ret == EINVAL)
                        break;
                if (ret)
@@ -373,8 +373,8 @@ static int checkInputAudioSet(struct node *node, __u32 audioset)
        int ret;
 
        ret = doioctl(node, VIDIOC_G_AUDIO, &input);
-       if (audioset == 0 && ret != EINVAL)
-               return fail("No audio inputs, but G_AUDIO did not return EINVAL\n");
+       if (audioset == 0 && ret != ENOTTY && ret != EINVAL)
+               return fail("No audio inputs, but G_AUDIO did not return ENOTTY or EINVAL\n");
        if (audioset) {
                if (ret)
                        return fail("Audio inputs, but G_AUDIO returned an error\n");
@@ -392,7 +392,7 @@ static int checkInputAudioSet(struct node *node, __u32 audioset)
                input.index = i;
                input.mode = 0;
                ret = doioctl(node, VIDIOC_S_AUDIO, &input);
-               if (!valid && ret != EINVAL)
+               if (!valid && ret != EINVAL && ret != ENOTTY)
                        return fail("can set invalid audio input %d\n", i);
                if (valid && ret)
                        return fail("can't set valid audio input %d\n", i);
@@ -420,7 +420,7 @@ int testInputAudio(struct node *node)
                if (checkInputAudioSet(node, vinput.audioset))
                        return fail("invalid audioset for input %d\n", i);
        }
-       return node->audio_inputs ? 0 : -ENOSYS;
+       return node->audio_inputs ? 0 : ENOTTY;
 }
 
 static int checkModulator(struct node *node, const struct v4l2_modulator &mod, unsigned m)
@@ -471,8 +471,8 @@ int testModulator(struct node *node)
                memset(mod.reserved, 0, sizeof(mod.reserved));
                mod.index = m;
                ret = doioctl(node, VIDIOC_G_MODULATOR, &mod);
-               if (ret == EINVAL && m == 0)
-                       return -ENOSYS;
+               if (ret == ENOTTY)
+                       return ret;
                if (ret == EINVAL)
                        break;
                if (ret)
@@ -559,15 +559,15 @@ int testModulatorFreq(struct node *node)
 
        freq.tuner = m;
        ret = doioctl(node, VIDIOC_G_FREQUENCY, &freq);
-       if (ret != EINVAL)
+       if (ret != EINVAL && ret != ENOTTY)
                return fail("could get frequency for invalid modulator %d\n", m);
        freq.tuner = m;
        // Radio: 100 MHz
        freq.frequency = 1600000;
        ret = doioctl(node, VIDIOC_S_FREQUENCY, &freq);
-       if (ret != EINVAL)
+       if (ret != EINVAL && ret != ENOTTY)
                return fail("could set frequency for invalid modulator %d\n", m);
-       return node->modulators ? 0 : -ENOSYS;
+       return node->modulators ? 0 : ENOTTY;
 }
 
 static int checkOutput(struct node *node, const struct v4l2_output &descr, unsigned o)
@@ -605,16 +605,15 @@ int testOutput(struct node *node)
        int ret = doioctl(node, VIDIOC_G_OUTPUT, &cur_output);
        int o = 0;
 
-       if (ret == EINVAL) {
+       if (ret == ENOTTY) {
                descr.index = 0;
                ret = doioctl(node, VIDIOC_ENUMOUTPUT, &descr);
-               if (ret != EINVAL)
+               if (ret != ENOTTY)
                        return fail("G_OUTPUT not supported, but ENUMOUTPUT is\n");
                output = 0;
                ret = doioctl(node, VIDIOC_S_OUTPUT, &output);
-               if (ret != EINVAL)
+               if (ret != ENOTTY)
                        return fail("G_OUTPUT not supported, but S_OUTPUT is\n");
-               return -ENOSYS;
        }
        if (ret)
                return ret;
@@ -674,8 +673,8 @@ int testEnumOutputAudio(struct node *node)
                output.index = o;
 
                ret = doioctl(node, VIDIOC_ENUMAUDOUT, &output);
-               if (o == 0 && ret == EINVAL)
-                       return -ENOSYS;
+               if (ret == ENOTTY)
+                       return ENOTTY;
                if (ret == EINVAL)
                        break;
                if (ret)
@@ -698,8 +697,8 @@ static int checkOutputAudioSet(struct node *node, __u32 audioset)
        int ret;
 
        ret = doioctl(node, VIDIOC_G_AUDOUT, &output);
-       if (audioset == 0 && ret != EINVAL)
-               return fail("No audio outputs, but G_AUDOUT did not return EINVAL\n");
+       if (audioset == 0 && ret != EINVAL && ret != ENOTTY)
+               return fail("No audio outputs, but G_AUDOUT did not return EINVAL or ENOTTY\n");
        if (audioset) {
                if (ret)
                        return fail("Audio outputs, but G_AUDOUT returned an error\n");
@@ -717,7 +716,7 @@ static int checkOutputAudioSet(struct node *node, __u32 audioset)
                output.index = i;
                output.mode = 0;
                ret = doioctl(node, VIDIOC_S_AUDOUT, &output);
-               if (!valid && ret != EINVAL)
+               if (!valid && ret != EINVAL && ret != ENOTTY)
                        return fail("can set invalid audio output %d\n", i);
                if (valid && ret)
                        return fail("can't set valid audio output %d\n", i);
@@ -748,5 +747,5 @@ int testOutputAudio(struct node *node)
 
        if (node->audio_outputs == 0 && node->audio_inputs && (caps & V4L2_CAP_AUDIO))
                return fail("no audio inputs or outputs reported, but CAP_AUDIO set\n");
-       return node->audio_outputs ? 0 : -ENOSYS;
+       return node->audio_outputs ? 0 : ENOTTY;
 }
index d2e89c3..35a17ef 100644 (file)
@@ -136,7 +136,7 @@ int testStd(struct node *node)
                if (checkStd(node, output.capabilities & V4L2_OUT_CAP_STD, output.std))
                        return fail("STD failed for output %d.\n", o);
        }
-       return has_std ? 0 : -ENOSYS;
+       return has_std ? 0 : ENOTTY;
 }
 
 static int checkPresets(struct node *node, bool has_presets)
@@ -163,7 +163,7 @@ static int checkPresets(struct node *node, bool has_presets)
        }
        preset.preset = V4L2_DV_INVALID;
        ret = doioctl(node, VIDIOC_S_DV_PRESET, &preset);
-       if (ret != EINVAL)
+       if (ret != EINVAL && ret != ENOTTY)
                return fail("could set preset V4L2_DV_INVALID\n");
 
        for (i = 0; ; i++) {
@@ -231,7 +231,7 @@ int testPresets(struct node *node)
                if (checkPresets(node, output.capabilities & V4L2_OUT_CAP_PRESETS))
                        return fail("Presets check failed for output %d.\n", o);
        }
-       return has_presets ? 0 : -ENOSYS;
+       return has_presets ? 0 : ENOTTY;
 }
 
 static int checkTimings(struct node *node, bool has_timings)
@@ -290,5 +290,5 @@ int testCustomTimings(struct node *node)
                if (checkTimings(node, output.capabilities & V4L2_OUT_CAP_CUSTOM_TIMINGS))
                        return fail("Custom timings check failed for output %d.\n", o);
        }
-       return has_timings ? 0 : -ENOSYS;
+       return has_timings ? 0 : ENOTTY;
 }