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>
{
static char buf[100];
- if (res == -ENOSYS) {
+ if (res == ENOTTY) {
strcpy(buf, "Not Supported");
res = 0;
} else {
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);
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)
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)
fail_on_test(memcmp(&orig, &chip, sizeof(chip)));
return 0;
}
- return ret == EINVAL ? -ENOSYS : ret;
+ return ret;
}
int testRegister(struct node *node)
reg.match.addr = 0;
reg.reg = 0;
ret = doioctl(node, VIDIOC_DBG_G_REGISTER, ®);
- 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);
// messing with registers in the compliance test.
reg.reg = reg.val = 0;
ret = doioctl(node, VIDIOC_DBG_S_REGISTER, ®);
- 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);
}
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;
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)
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:
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:
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)
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");
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:
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]))
}
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;
}
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;
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:
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",
}
ret = testFormatsType(node, V4L2_BUF_TYPE_PRIVATE);
- if (ret > 0)
+ if (ret && ret != ENOTTY)
return ret;
if (!ret)
warn("Buffer type PRIVATE allowed!\n");
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++)
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)
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)
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");
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)
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");
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);
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)
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)
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)
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;
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)
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");
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);
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;
}
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)
}
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++) {
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)
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;
}