/* v4l-ioctl-test - This small utility sends dumb v4l2 ioctl to a device. It is meant to check ioctl debug messages generated and to check if a function is implemented by that device. Copyright (C) 2005 Mauro Carvalho Chehab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #define __OLD_VIDIOC_ #include "linux/videodev.h" /* All possible parameters used on v4l ioctls */ union v4l_parms { int i; unsigned long ulong; u_int32_t u32; v4l2_std_id id; enum v4l2_priority prio; #ifdef CONFIG_VIDEO_V4L1_COMPAT /* V4L1 structs */ struct video_capability p_video_capability; struct video_channel p_video_channel; struct video_tuner p_video_tuner; struct video_picture p_video_picture; struct video_window p_video_window; struct video_buffer p_video_buffer; struct video_key p_video_key; struct video_audio p_video_audio; struct video_mmap p_video_mmap; struct video_mbuf p_video_mbuf; struct video_unit p_video_unit; struct video_capture p_video_capture; struct video_play_mode p_video_play_mode; struct video_info p_video_info; struct video_code p_video_code; struct vbi_format p_vbi_format; #endif /* V4L2 structs */ struct v4l2_capability p_v4l2_capability; struct v4l2_fmtdesc p_v4l2_fmtdesc; struct v4l2_format p_v4l2_format; struct v4l2_requestbuffers p_v4l2_requestbuffers; struct v4l2_buffer p_v4l2_buffer; struct v4l2_framebuffer p_v4l2_framebuffer; struct v4l2_streamparm p_v4l2_streamparm; struct v4l2_standard p_v4l2_standard; struct v4l2_input p_v4l2_input; struct v4l2_control p_v4l2_control; struct v4l2_tuner p_v4l2_tuner; struct v4l2_audio p_v4l2_audio; struct v4l2_queryctrl p_v4l2_queryctrl; struct v4l2_querymenu p_v4l2_querymenu; struct v4l2_output p_v4l2_output; struct v4l2_audioout p_v4l2_audioout; struct v4l2_modulator p_v4l2_modulator; struct v4l2_frequency p_v4l2_frequency; struct v4l2_cropcap p_v4l2_cropcap; struct v4l2_crop p_v4l2_crop; struct v4l2_jpegcompression p_v4l2_jpegcompression; struct v4l2_sliced_vbi_cap p_v4l2_sliced_vbi_cap; struct v4l2_ext_controls p_v4l2_ext_controls; struct v4l2_frmsizeenum p_v4l2_frmsizeenum; struct v4l2_frmivalenum p_v4l2_frmivalenum; struct v4l2_enc_idx p_v4l2_enc_idx; struct v4l2_encoder_cmd p_v4l2_encoder_cmd; struct v4l2_dbg_register p_v4l2_dbg_register; struct v4l2_dbg_chip_ident p_v4l2_dbg_chip_ident; struct v4l2_hw_freq_seek p_v4l2_hw_freq_seek; }; #define ioc(cmd) { cmd, #cmd } /* All defined ioctls */ static const struct { u_int32_t cmd; const char *name; } ioctls[] = { #ifdef CONFIG_VIDEO_V4L1_COMPAT /* V4L1 ioctls */ ioc(VIDIOCGCAP), /* struct video_capability */ ioc(VIDIOCGCHAN), /* struct video_channel */ ioc(VIDIOCSCHAN), /* struct video_channel */ ioc(VIDIOCGTUNER), /* struct video_tuner */ ioc(VIDIOCSTUNER), /* struct video_tuner */ ioc(VIDIOCGPICT), /* struct video_picture */ ioc(VIDIOCSPICT), /* struct video_picture */ ioc(VIDIOCCAPTURE), /* int */ ioc(VIDIOCGWIN), /* struct video_window */ ioc(VIDIOCSWIN), /* struct video_window */ ioc(VIDIOCGFBUF), /* struct video_buffer */ ioc(VIDIOCSFBUF), /* struct video_buffer */ ioc(VIDIOCKEY), /* struct video_key */ ioc(VIDIOCGFREQ), /* unsigned long */ ioc(VIDIOCSFREQ), /* unsigned long */ ioc(VIDIOCGAUDIO), /* struct video_audio */ ioc(VIDIOCSAUDIO), /* struct video_audio */ ioc(VIDIOCSYNC), /* int */ ioc(VIDIOCMCAPTURE), /* struct video_mmap */ ioc(VIDIOCGMBUF), /* struct video_mbuf */ ioc(VIDIOCGUNIT), /* struct video_unit */ ioc(VIDIOCGCAPTURE), /* struct video_capture */ ioc(VIDIOCSCAPTURE), /* struct video_capture */ ioc(VIDIOCSPLAYMODE), /* struct video_play_mode */ ioc(VIDIOCSWRITEMODE), /* int */ ioc(VIDIOCGPLAYINFO), /* struct video_info */ ioc(VIDIOCSMICROCODE), /* struct video_code */ ioc(VIDIOCGVBIFMT), /* struct vbi_format */ ioc(VIDIOCSVBIFMT), /* struct vbi_format */ #endif /* V4L2 ioctls */ ioc(VIDIOC_QUERYCAP), /* struct v4l2_capability */ ioc(VIDIOC_RESERVED), ioc(VIDIOC_ENUM_FMT), /* struct v4l2_fmtdesc */ ioc(VIDIOC_G_FMT), /* struct v4l2_format */ ioc(VIDIOC_S_FMT), /* struct v4l2_format */ ioc(VIDIOC_REQBUFS), /* struct v4l2_requestbuffers */ ioc(VIDIOC_QUERYBUF), /* struct v4l2_buffer */ ioc(VIDIOC_G_FBUF), /* struct v4l2_framebuffer */ ioc(VIDIOC_S_FBUF), /* struct v4l2_framebuffer */ ioc(VIDIOC_OVERLAY), /* int */ ioc(VIDIOC_QBUF), /* struct v4l2_buffer */ ioc(VIDIOC_DQBUF), /* struct v4l2_buffer */ ioc(VIDIOC_STREAMON), /* int */ ioc(VIDIOC_STREAMOFF), /* int */ ioc(VIDIOC_G_PARM), /* struct v4l2_streamparm */ ioc(VIDIOC_S_PARM), /* struct v4l2_streamparm */ ioc(VIDIOC_G_STD), /* v4l2_std_id */ ioc(VIDIOC_S_STD), /* v4l2_std_id */ ioc(VIDIOC_ENUMSTD), /* struct v4l2_standard */ ioc(VIDIOC_ENUMINPUT), /* struct v4l2_input */ ioc(VIDIOC_G_CTRL), /* struct v4l2_control */ ioc(VIDIOC_S_CTRL), /* struct v4l2_control */ ioc(VIDIOC_G_TUNER), /* struct v4l2_tuner */ ioc(VIDIOC_S_TUNER), /* struct v4l2_tuner */ ioc(VIDIOC_G_AUDIO), /* struct v4l2_audio */ ioc(VIDIOC_S_AUDIO), /* struct v4l2_audio */ ioc(VIDIOC_QUERYCTRL), /* struct v4l2_queryctrl */ ioc(VIDIOC_QUERYMENU), /* struct v4l2_querymenu */ ioc(VIDIOC_G_INPUT), /* int */ ioc(VIDIOC_S_INPUT), /* int */ ioc(VIDIOC_G_OUTPUT), /* int */ ioc(VIDIOC_S_OUTPUT), /* int */ ioc(VIDIOC_ENUMOUTPUT), /* struct v4l2_output */ ioc(VIDIOC_G_AUDOUT), /* struct v4l2_audioout */ ioc(VIDIOC_S_AUDOUT), /* struct v4l2_audioout */ ioc(VIDIOC_G_MODULATOR), /* struct v4l2_modulator */ ioc(VIDIOC_S_MODULATOR), /* struct v4l2_modulator */ ioc(VIDIOC_G_FREQUENCY), /* struct v4l2_frequency */ ioc(VIDIOC_S_FREQUENCY), /* struct v4l2_frequency */ ioc(VIDIOC_CROPCAP), /* struct v4l2_cropcap */ ioc(VIDIOC_G_CROP), /* struct v4l2_crop */ ioc(VIDIOC_S_CROP), /* struct v4l2_crop */ ioc(VIDIOC_G_JPEGCOMP), /* struct v4l2_jpegcompression */ ioc(VIDIOC_S_JPEGCOMP), /* struct v4l2_jpegcompression */ ioc(VIDIOC_QUERYSTD), /* v4l2_std_id */ ioc(VIDIOC_TRY_FMT), /* struct v4l2_format */ ioc(VIDIOC_ENUMAUDIO), /* struct v4l2_audio */ ioc(VIDIOC_ENUMAUDOUT), /* struct v4l2_audioout */ ioc(VIDIOC_G_PRIORITY), /* enum v4l2_priority */ ioc(VIDIOC_S_PRIORITY), /* enum v4l2_priority */ ioc(VIDIOC_G_SLICED_VBI_CAP), /* struct v4l2_sliced_vbi_cap */ ioc(VIDIOC_LOG_STATUS), ioc(VIDIOC_G_EXT_CTRLS), /* struct v4l2_ext_controls */ ioc(VIDIOC_S_EXT_CTRLS), /* struct v4l2_ext_controls */ ioc(VIDIOC_TRY_EXT_CTRLS), /* struct v4l2_ext_controls */ ioc(VIDIOC_ENUM_FRAMESIZES), /* struct v4l2_frmsizeenum */ ioc(VIDIOC_ENUM_FRAMEINTERVALS),/* struct v4l2_frmivalenum */ ioc(VIDIOC_G_ENC_INDEX), /* struct v4l2_enc_idx */ ioc(VIDIOC_ENCODER_CMD), /* struct v4l2_encoder_cmd */ ioc(VIDIOC_TRY_ENCODER_CMD), /* struct v4l2_encoder_cmd */ ioc(VIDIOC_DBG_S_REGISTER), /* struct v4l2_register */ ioc(VIDIOC_DBG_G_REGISTER), /* struct v4l2_register */ ioc(VIDIOC_DBG_G_CHIP_IDENT), /* struct v4l2_dbg_chip_ident */ ioc(VIDIOC_S_HW_FREQ_SEEK), /* struct v4l2_hw_freq_seek */ #ifdef __OLD_VIDIOC_ ioc(VIDIOC_OVERLAY_OLD), /* int */ ioc(VIDIOC_S_PARM_OLD), /* struct v4l2_streamparm */ ioc(VIDIOC_S_CTRL_OLD), /* struct v4l2_control */ ioc(VIDIOC_G_AUDIO_OLD), /* struct v4l2_audio */ ioc(VIDIOC_G_AUDOUT_OLD), /* struct v4l2_audioout */ ioc(VIDIOC_CROPCAP_OLD), /* struct v4l2_cropcap */ #endif }; #define S_IOCTLS sizeof(ioctls)/sizeof(ioctls[0]) /********************************************************************/ int main(int argc, char **argv) { int fd = 0, ret = 0; unsigned i; unsigned maxlen = 0; char *device = "/dev/video0"; char marker[8] = { 0xde, 0xad, 0xbe, 0xef, 0xad, 0xbc, 0xcb, 0xda }; char p[sizeof(union v4l_parms) + 2 * sizeof(marker)]; static const char *dirs[] = { " IO", " IOW", " IOR", "IOWR" }; if (argv[1]) device = argv[1]; if ((fd = open(device, O_RDONLY)) < 0) { fprintf(stderr, "Couldn't open %s\n", device); return -1; } for (i = 0; i < S_IOCTLS; i++) { if (strlen(ioctls[i].name) > maxlen) maxlen = strlen(ioctls[i].name); } for (i = 0; i < S_IOCTLS; i++) { char buf[maxlen + 100]; const char *name = ioctls[i].name; u_int32_t cmd = ioctls[i].cmd; int dir = _IOC_DIR(cmd); char type = _IOC_TYPE(cmd); int nr = _IOC_NR(cmd); int sz = _IOC_SIZE(cmd); /* Check whether the front and back markers aren't overwritten. Useful to verify the compat32 code. */ memset(&p, 0, sizeof(p)); memcpy(p, marker, sizeof(marker)); memcpy(p + sz + sizeof(marker), marker, sizeof(marker)); sprintf(buf, "ioctl 0x%08x = %s('%c', %2d, %4d) = %-*s", cmd, dirs[dir], type, nr, sz, maxlen, name); errno = 0; ret = ioctl(fd, cmd, (void *)&p[sizeof(marker)]); perror(buf); if (memcmp(p, marker, sizeof(marker))) fprintf(stderr, "%s: front marker overwritten!\n", name); if (memcmp(p + sizeof(marker) + sz, marker, sizeof(marker))) fprintf(stderr, "%s: back marker overwritten!\n", name); } close (fd); return 0; }