Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.32 1951 lines 52 kB view raw
1/* 2 * Video capture interface for Linux version 2 3 * 4 * A generic framework to process V4L2 ioctl commands. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 * 11 * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) 12 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2) 13 */ 14 15#include <linux/module.h> 16#include <linux/types.h> 17#include <linux/kernel.h> 18 19#define __OLD_VIDIOC_ /* To allow fixing old calls */ 20#include <linux/videodev.h> 21#include <linux/videodev2.h> 22 23#ifdef CONFIG_VIDEO_V4L1 24#include <linux/videodev.h> 25#endif 26#include <media/v4l2-common.h> 27#include <media/v4l2-ioctl.h> 28#include <media/v4l2-chip-ident.h> 29 30#define dbgarg(cmd, fmt, arg...) \ 31 do { \ 32 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ 33 printk(KERN_DEBUG "%s: ", vfd->name); \ 34 v4l_printk_ioctl(cmd); \ 35 printk(" " fmt, ## arg); \ 36 } \ 37 } while (0) 38 39#define dbgarg2(fmt, arg...) \ 40 do { \ 41 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ 42 printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\ 43 } while (0) 44 45#define dbgarg3(fmt, arg...) \ 46 do { \ 47 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ 48 printk(KERN_CONT "%s: " fmt, vfd->name, ## arg);\ 49 } while (0) 50 51/* Zero out the end of the struct pointed to by p. Everthing after, but 52 * not including, the specified field is cleared. */ 53#define CLEAR_AFTER_FIELD(p, field) \ 54 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \ 55 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field)) 56 57struct std_descr { 58 v4l2_std_id std; 59 const char *descr; 60}; 61 62static const struct std_descr standards[] = { 63 { V4L2_STD_NTSC, "NTSC" }, 64 { V4L2_STD_NTSC_M, "NTSC-M" }, 65 { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, 66 { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" }, 67 { V4L2_STD_NTSC_443, "NTSC-443" }, 68 { V4L2_STD_PAL, "PAL" }, 69 { V4L2_STD_PAL_BG, "PAL-BG" }, 70 { V4L2_STD_PAL_B, "PAL-B" }, 71 { V4L2_STD_PAL_B1, "PAL-B1" }, 72 { V4L2_STD_PAL_G, "PAL-G" }, 73 { V4L2_STD_PAL_H, "PAL-H" }, 74 { V4L2_STD_PAL_I, "PAL-I" }, 75 { V4L2_STD_PAL_DK, "PAL-DK" }, 76 { V4L2_STD_PAL_D, "PAL-D" }, 77 { V4L2_STD_PAL_D1, "PAL-D1" }, 78 { V4L2_STD_PAL_K, "PAL-K" }, 79 { V4L2_STD_PAL_M, "PAL-M" }, 80 { V4L2_STD_PAL_N, "PAL-N" }, 81 { V4L2_STD_PAL_Nc, "PAL-Nc" }, 82 { V4L2_STD_PAL_60, "PAL-60" }, 83 { V4L2_STD_SECAM, "SECAM" }, 84 { V4L2_STD_SECAM_B, "SECAM-B" }, 85 { V4L2_STD_SECAM_G, "SECAM-G" }, 86 { V4L2_STD_SECAM_H, "SECAM-H" }, 87 { V4L2_STD_SECAM_DK, "SECAM-DK" }, 88 { V4L2_STD_SECAM_D, "SECAM-D" }, 89 { V4L2_STD_SECAM_K, "SECAM-K" }, 90 { V4L2_STD_SECAM_K1, "SECAM-K1" }, 91 { V4L2_STD_SECAM_L, "SECAM-L" }, 92 { V4L2_STD_SECAM_LC, "SECAM-Lc" }, 93 { 0, "Unknown" } 94}; 95 96/* video4linux standard ID conversion to standard name 97 */ 98const char *v4l2_norm_to_name(v4l2_std_id id) 99{ 100 u32 myid = id; 101 int i; 102 103 /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle 104 64 bit comparations. So, on that architecture, with some gcc 105 variants, compilation fails. Currently, the max value is 30bit wide. 106 */ 107 BUG_ON(myid != id); 108 109 for (i = 0; standards[i].std; i++) 110 if (myid == standards[i].std) 111 break; 112 return standards[i].descr; 113} 114EXPORT_SYMBOL(v4l2_norm_to_name); 115 116/* Returns frame period for the given standard */ 117void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod) 118{ 119 if (id & V4L2_STD_525_60) { 120 frameperiod->numerator = 1001; 121 frameperiod->denominator = 30000; 122 } else { 123 frameperiod->numerator = 1; 124 frameperiod->denominator = 25; 125 } 126} 127EXPORT_SYMBOL(v4l2_video_std_frame_period); 128 129/* Fill in the fields of a v4l2_standard structure according to the 130 'id' and 'transmission' parameters. Returns negative on error. */ 131int v4l2_video_std_construct(struct v4l2_standard *vs, 132 int id, const char *name) 133{ 134 vs->id = id; 135 v4l2_video_std_frame_period(id, &vs->frameperiod); 136 vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625; 137 strlcpy(vs->name, name, sizeof(vs->name)); 138 return 0; 139} 140EXPORT_SYMBOL(v4l2_video_std_construct); 141 142/* ----------------------------------------------------------------- */ 143/* some arrays for pretty-printing debug messages of enum types */ 144 145const char *v4l2_field_names[] = { 146 [V4L2_FIELD_ANY] = "any", 147 [V4L2_FIELD_NONE] = "none", 148 [V4L2_FIELD_TOP] = "top", 149 [V4L2_FIELD_BOTTOM] = "bottom", 150 [V4L2_FIELD_INTERLACED] = "interlaced", 151 [V4L2_FIELD_SEQ_TB] = "seq-tb", 152 [V4L2_FIELD_SEQ_BT] = "seq-bt", 153 [V4L2_FIELD_ALTERNATE] = "alternate", 154 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", 155 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", 156}; 157EXPORT_SYMBOL(v4l2_field_names); 158 159const char *v4l2_type_names[] = { 160 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap", 161 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay", 162 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out", 163 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", 164 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", 165 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", 166 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", 167 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", 168}; 169EXPORT_SYMBOL(v4l2_type_names); 170 171static const char *v4l2_memory_names[] = { 172 [V4L2_MEMORY_MMAP] = "mmap", 173 [V4L2_MEMORY_USERPTR] = "userptr", 174 [V4L2_MEMORY_OVERLAY] = "overlay", 175}; 176 177#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \ 178 arr[a] : "unknown") 179 180/* ------------------------------------------------------------------ */ 181/* debug help functions */ 182 183#ifdef CONFIG_VIDEO_V4L1_COMPAT 184static const char *v4l1_ioctls[] = { 185 [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", 186 [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", 187 [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", 188 [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", 189 [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", 190 [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", 191 [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", 192 [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", 193 [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", 194 [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", 195 [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", 196 [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", 197 [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", 198 [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", 199 [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", 200 [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", 201 [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", 202 [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", 203 [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", 204 [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", 205 [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", 206 [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", 207 [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", 208 [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", 209 [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", 210 [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", 211 [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", 212 [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", 213 [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT" 214}; 215#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) 216#endif 217 218static const char *v4l2_ioctls[] = { 219 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", 220 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", 221 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", 222 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", 223 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", 224 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", 225 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", 226 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", 227 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", 228 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", 229 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", 230 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", 231 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", 232 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", 233 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", 234 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", 235 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", 236 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", 237 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", 238 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", 239 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", 240 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", 241 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", 242 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", 243 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", 244 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", 245 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", 246 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", 247 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", 248 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", 249 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", 250 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", 251 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", 252 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", 253 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", 254 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", 255 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", 256 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", 257 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", 258 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", 259 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", 260 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", 261 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", 262 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", 263 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", 264 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", 265 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", 266 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", 267 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", 268 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", 269 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", 270 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", 271 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", 272 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", 273 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", 274#if 1 275 [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", 276 [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", 277 [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX", 278 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", 279 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", 280 281 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", 282 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", 283 284 [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", 285 [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", 286#endif 287}; 288#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) 289 290/* Common ioctl debug function. This function can be used by 291 external ioctl messages as well as internal V4L ioctl */ 292void v4l_printk_ioctl(unsigned int cmd) 293{ 294 char *dir, *type; 295 296 switch (_IOC_TYPE(cmd)) { 297 case 'd': 298 type = "v4l2_int"; 299 break; 300#ifdef CONFIG_VIDEO_V4L1_COMPAT 301 case 'v': 302 if (_IOC_NR(cmd) >= V4L1_IOCTLS) { 303 type = "v4l1"; 304 break; 305 } 306 printk("%s", v4l1_ioctls[_IOC_NR(cmd)]); 307 return; 308#endif 309 case 'V': 310 if (_IOC_NR(cmd) >= V4L2_IOCTLS) { 311 type = "v4l2"; 312 break; 313 } 314 printk("%s", v4l2_ioctls[_IOC_NR(cmd)]); 315 return; 316 default: 317 type = "unknown"; 318 } 319 320 switch (_IOC_DIR(cmd)) { 321 case _IOC_NONE: dir = "--"; break; 322 case _IOC_READ: dir = "r-"; break; 323 case _IOC_WRITE: dir = "-w"; break; 324 case _IOC_READ | _IOC_WRITE: dir = "rw"; break; 325 default: dir = "*ERR*"; break; 326 } 327 printk("%s ioctl '%c', dir=%s, #%d (0x%08x)", 328 type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); 329} 330EXPORT_SYMBOL(v4l_printk_ioctl); 331 332/* 333 * helper function -- handles userspace copying for ioctl arguments 334 */ 335 336#ifdef __OLD_VIDIOC_ 337static unsigned int 338video_fix_command(unsigned int cmd) 339{ 340 switch (cmd) { 341 case VIDIOC_OVERLAY_OLD: 342 cmd = VIDIOC_OVERLAY; 343 break; 344 case VIDIOC_S_PARM_OLD: 345 cmd = VIDIOC_S_PARM; 346 break; 347 case VIDIOC_S_CTRL_OLD: 348 cmd = VIDIOC_S_CTRL; 349 break; 350 case VIDIOC_G_AUDIO_OLD: 351 cmd = VIDIOC_G_AUDIO; 352 break; 353 case VIDIOC_G_AUDOUT_OLD: 354 cmd = VIDIOC_G_AUDOUT; 355 break; 356 case VIDIOC_CROPCAP_OLD: 357 cmd = VIDIOC_CROPCAP; 358 break; 359 } 360 return cmd; 361} 362#endif 363 364/* 365 * Obsolete usercopy function - Should be removed soon 366 */ 367long 368video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, 369 v4l2_kioctl func) 370{ 371 char sbuf[128]; 372 void *mbuf = NULL; 373 void *parg = NULL; 374 long err = -EINVAL; 375 int is_ext_ctrl; 376 size_t ctrls_size = 0; 377 void __user *user_ptr = NULL; 378 379#ifdef __OLD_VIDIOC_ 380 cmd = video_fix_command(cmd); 381#endif 382 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || 383 cmd == VIDIOC_TRY_EXT_CTRLS); 384 385 /* Copy arguments into temp kernel buffer */ 386 switch (_IOC_DIR(cmd)) { 387 case _IOC_NONE: 388 parg = NULL; 389 break; 390 case _IOC_READ: 391 case _IOC_WRITE: 392 case (_IOC_WRITE | _IOC_READ): 393 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { 394 parg = sbuf; 395 } else { 396 /* too big to allocate from stack */ 397 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); 398 if (NULL == mbuf) 399 return -ENOMEM; 400 parg = mbuf; 401 } 402 403 err = -EFAULT; 404 if (_IOC_DIR(cmd) & _IOC_WRITE) 405 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) 406 goto out; 407 break; 408 } 409 if (is_ext_ctrl) { 410 struct v4l2_ext_controls *p = parg; 411 412 /* In case of an error, tell the caller that it wasn't 413 a specific control that caused it. */ 414 p->error_idx = p->count; 415 user_ptr = (void __user *)p->controls; 416 if (p->count) { 417 ctrls_size = sizeof(struct v4l2_ext_control) * p->count; 418 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ 419 mbuf = kmalloc(ctrls_size, GFP_KERNEL); 420 err = -ENOMEM; 421 if (NULL == mbuf) 422 goto out_ext_ctrl; 423 err = -EFAULT; 424 if (copy_from_user(mbuf, user_ptr, ctrls_size)) 425 goto out_ext_ctrl; 426 p->controls = mbuf; 427 } 428 } 429 430 /* call driver */ 431 err = func(file, cmd, parg); 432 if (err == -ENOIOCTLCMD) 433 err = -EINVAL; 434 if (is_ext_ctrl) { 435 struct v4l2_ext_controls *p = parg; 436 437 p->controls = (void *)user_ptr; 438 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) 439 err = -EFAULT; 440 goto out_ext_ctrl; 441 } 442 if (err < 0) 443 goto out; 444 445out_ext_ctrl: 446 /* Copy results into user buffer */ 447 switch (_IOC_DIR(cmd)) { 448 case _IOC_READ: 449 case (_IOC_WRITE | _IOC_READ): 450 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) 451 err = -EFAULT; 452 break; 453 } 454 455out: 456 kfree(mbuf); 457 return err; 458} 459EXPORT_SYMBOL(video_usercopy); 460 461static void dbgbuf(unsigned int cmd, struct video_device *vfd, 462 struct v4l2_buffer *p) 463{ 464 struct v4l2_timecode *tc = &p->timecode; 465 466 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, " 467 "bytesused=%d, flags=0x%08d, " 468 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n", 469 p->timestamp.tv_sec / 3600, 470 (int)(p->timestamp.tv_sec / 60) % 60, 471 (int)(p->timestamp.tv_sec % 60), 472 (long)p->timestamp.tv_usec, 473 p->index, 474 prt_names(p->type, v4l2_type_names), 475 p->bytesused, p->flags, 476 p->field, p->sequence, 477 prt_names(p->memory, v4l2_memory_names), 478 p->m.userptr, p->length); 479 dbgarg2("timecode=%02d:%02d:%02d type=%d, " 480 "flags=0x%08d, frames=%d, userbits=0x%08x\n", 481 tc->hours, tc->minutes, tc->seconds, 482 tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits); 483} 484 485static inline void dbgrect(struct video_device *vfd, char *s, 486 struct v4l2_rect *r) 487{ 488 dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top, 489 r->width, r->height); 490}; 491 492static inline void v4l_print_pix_fmt(struct video_device *vfd, 493 struct v4l2_pix_format *fmt) 494{ 495 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, " 496 "bytesperline=%d sizeimage=%d, colorspace=%d\n", 497 fmt->width, fmt->height, 498 (fmt->pixelformat & 0xff), 499 (fmt->pixelformat >> 8) & 0xff, 500 (fmt->pixelformat >> 16) & 0xff, 501 (fmt->pixelformat >> 24) & 0xff, 502 prt_names(fmt->field, v4l2_field_names), 503 fmt->bytesperline, fmt->sizeimage, fmt->colorspace); 504}; 505 506static inline void v4l_print_ext_ctrls(unsigned int cmd, 507 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals) 508{ 509 __u32 i; 510 511 if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) 512 return; 513 dbgarg(cmd, ""); 514 printk(KERN_CONT "class=0x%x", c->ctrl_class); 515 for (i = 0; i < c->count; i++) { 516 if (show_vals && !c->controls[i].size) 517 printk(KERN_CONT " id/val=0x%x/0x%x", 518 c->controls[i].id, c->controls[i].value); 519 else 520 printk(KERN_CONT " id=0x%x,size=%u", 521 c->controls[i].id, c->controls[i].size); 522 } 523 printk(KERN_CONT "\n"); 524}; 525 526static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) 527{ 528 __u32 i; 529 530 /* zero the reserved fields */ 531 c->reserved[0] = c->reserved[1] = 0; 532 for (i = 0; i < c->count; i++) 533 c->controls[i].reserved2[0] = 0; 534 535 /* V4L2_CID_PRIVATE_BASE cannot be used as control class 536 when using extended controls. 537 Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL 538 is it allowed for backwards compatibility. 539 */ 540 if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE) 541 return 0; 542 /* Check that all controls are from the same control class. */ 543 for (i = 0; i < c->count; i++) { 544 if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) { 545 c->error_idx = i; 546 return 0; 547 } 548 } 549 return 1; 550} 551 552static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) 553{ 554 if (ops == NULL) 555 return -EINVAL; 556 557 switch (type) { 558 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 559 if (ops->vidioc_g_fmt_vid_cap) 560 return 0; 561 break; 562 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 563 if (ops->vidioc_g_fmt_vid_overlay) 564 return 0; 565 break; 566 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 567 if (ops->vidioc_g_fmt_vid_out) 568 return 0; 569 break; 570 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 571 if (ops->vidioc_g_fmt_vid_out_overlay) 572 return 0; 573 break; 574 case V4L2_BUF_TYPE_VBI_CAPTURE: 575 if (ops->vidioc_g_fmt_vbi_cap) 576 return 0; 577 break; 578 case V4L2_BUF_TYPE_VBI_OUTPUT: 579 if (ops->vidioc_g_fmt_vbi_out) 580 return 0; 581 break; 582 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 583 if (ops->vidioc_g_fmt_sliced_vbi_cap) 584 return 0; 585 break; 586 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 587 if (ops->vidioc_g_fmt_sliced_vbi_out) 588 return 0; 589 break; 590 case V4L2_BUF_TYPE_PRIVATE: 591 if (ops->vidioc_g_fmt_type_private) 592 return 0; 593 break; 594 } 595 return -EINVAL; 596} 597 598static long __video_do_ioctl(struct file *file, 599 unsigned int cmd, void *arg) 600{ 601 struct video_device *vfd = video_devdata(file); 602 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; 603 void *fh = file->private_data; 604 long ret = -EINVAL; 605 606 if ((vfd->debug & V4L2_DEBUG_IOCTL) && 607 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { 608 v4l_print_ioctl(vfd->name, cmd); 609 printk(KERN_CONT "\n"); 610 } 611 612 if (ops == NULL) { 613 printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n", 614 vfd->name); 615 return -EINVAL; 616 } 617 618#ifdef CONFIG_VIDEO_V4L1_COMPAT 619 /*********************************************************** 620 Handles calls to the obsoleted V4L1 API 621 Due to the nature of VIDIOCGMBUF, each driver that supports 622 V4L1 should implement its own handler for this ioctl. 623 ***********************************************************/ 624 625 /* --- streaming capture ------------------------------------- */ 626 if (cmd == VIDIOCGMBUF) { 627 struct video_mbuf *p = arg; 628 629 if (!ops->vidiocgmbuf) 630 return ret; 631 ret = ops->vidiocgmbuf(file, fh, p); 632 if (!ret) 633 dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n", 634 p->size, p->frames, 635 (unsigned long)p->offsets); 636 return ret; 637 } 638 639 /******************************************************** 640 All other V4L1 calls are handled by v4l1_compat module. 641 Those calls will be translated into V4L2 calls, and 642 __video_do_ioctl will be called again, with one or more 643 V4L2 ioctls. 644 ********************************************************/ 645 if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE) 646 return v4l_compat_translate_ioctl(file, cmd, arg, 647 __video_do_ioctl); 648#endif 649 650 switch (cmd) { 651 /* --- capabilities ------------------------------------------ */ 652 case VIDIOC_QUERYCAP: 653 { 654 struct v4l2_capability *cap = (struct v4l2_capability *)arg; 655 656 if (!ops->vidioc_querycap) 657 break; 658 659 ret = ops->vidioc_querycap(file, fh, cap); 660 if (!ret) 661 dbgarg(cmd, "driver=%s, card=%s, bus=%s, " 662 "version=0x%08x, " 663 "capabilities=0x%08x\n", 664 cap->driver, cap->card, cap->bus_info, 665 cap->version, 666 cap->capabilities); 667 break; 668 } 669 670 /* --- priority ------------------------------------------ */ 671 case VIDIOC_G_PRIORITY: 672 { 673 enum v4l2_priority *p = arg; 674 675 if (!ops->vidioc_g_priority) 676 break; 677 ret = ops->vidioc_g_priority(file, fh, p); 678 if (!ret) 679 dbgarg(cmd, "priority is %d\n", *p); 680 break; 681 } 682 case VIDIOC_S_PRIORITY: 683 { 684 enum v4l2_priority *p = arg; 685 686 if (!ops->vidioc_s_priority) 687 break; 688 dbgarg(cmd, "setting priority to %d\n", *p); 689 ret = ops->vidioc_s_priority(file, fh, *p); 690 break; 691 } 692 693 /* --- capture ioctls ---------------------------------------- */ 694 case VIDIOC_ENUM_FMT: 695 { 696 struct v4l2_fmtdesc *f = arg; 697 698 switch (f->type) { 699 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 700 if (ops->vidioc_enum_fmt_vid_cap) 701 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); 702 break; 703 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 704 if (ops->vidioc_enum_fmt_vid_overlay) 705 ret = ops->vidioc_enum_fmt_vid_overlay(file, 706 fh, f); 707 break; 708 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 709 if (ops->vidioc_enum_fmt_vid_out) 710 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f); 711 break; 712 case V4L2_BUF_TYPE_PRIVATE: 713 if (ops->vidioc_enum_fmt_type_private) 714 ret = ops->vidioc_enum_fmt_type_private(file, 715 fh, f); 716 break; 717 default: 718 break; 719 } 720 if (!ret) 721 dbgarg(cmd, "index=%d, type=%d, flags=%d, " 722 "pixelformat=%c%c%c%c, description='%s'\n", 723 f->index, f->type, f->flags, 724 (f->pixelformat & 0xff), 725 (f->pixelformat >> 8) & 0xff, 726 (f->pixelformat >> 16) & 0xff, 727 (f->pixelformat >> 24) & 0xff, 728 f->description); 729 break; 730 } 731 case VIDIOC_G_FMT: 732 { 733 struct v4l2_format *f = (struct v4l2_format *)arg; 734 735 /* FIXME: Should be one dump per type */ 736 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); 737 738 switch (f->type) { 739 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 740 if (ops->vidioc_g_fmt_vid_cap) 741 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f); 742 if (!ret) 743 v4l_print_pix_fmt(vfd, &f->fmt.pix); 744 break; 745 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 746 if (ops->vidioc_g_fmt_vid_overlay) 747 ret = ops->vidioc_g_fmt_vid_overlay(file, 748 fh, f); 749 break; 750 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 751 if (ops->vidioc_g_fmt_vid_out) 752 ret = ops->vidioc_g_fmt_vid_out(file, fh, f); 753 if (!ret) 754 v4l_print_pix_fmt(vfd, &f->fmt.pix); 755 break; 756 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 757 if (ops->vidioc_g_fmt_vid_out_overlay) 758 ret = ops->vidioc_g_fmt_vid_out_overlay(file, 759 fh, f); 760 break; 761 case V4L2_BUF_TYPE_VBI_CAPTURE: 762 if (ops->vidioc_g_fmt_vbi_cap) 763 ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f); 764 break; 765 case V4L2_BUF_TYPE_VBI_OUTPUT: 766 if (ops->vidioc_g_fmt_vbi_out) 767 ret = ops->vidioc_g_fmt_vbi_out(file, fh, f); 768 break; 769 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 770 if (ops->vidioc_g_fmt_sliced_vbi_cap) 771 ret = ops->vidioc_g_fmt_sliced_vbi_cap(file, 772 fh, f); 773 break; 774 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 775 if (ops->vidioc_g_fmt_sliced_vbi_out) 776 ret = ops->vidioc_g_fmt_sliced_vbi_out(file, 777 fh, f); 778 break; 779 case V4L2_BUF_TYPE_PRIVATE: 780 if (ops->vidioc_g_fmt_type_private) 781 ret = ops->vidioc_g_fmt_type_private(file, 782 fh, f); 783 break; 784 } 785 786 break; 787 } 788 case VIDIOC_S_FMT: 789 { 790 struct v4l2_format *f = (struct v4l2_format *)arg; 791 792 /* FIXME: Should be one dump per type */ 793 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); 794 795 switch (f->type) { 796 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 797 CLEAR_AFTER_FIELD(f, fmt.pix); 798 v4l_print_pix_fmt(vfd, &f->fmt.pix); 799 if (ops->vidioc_s_fmt_vid_cap) 800 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); 801 break; 802 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 803 CLEAR_AFTER_FIELD(f, fmt.win); 804 if (ops->vidioc_s_fmt_vid_overlay) 805 ret = ops->vidioc_s_fmt_vid_overlay(file, 806 fh, f); 807 break; 808 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 809 CLEAR_AFTER_FIELD(f, fmt.pix); 810 v4l_print_pix_fmt(vfd, &f->fmt.pix); 811 if (ops->vidioc_s_fmt_vid_out) 812 ret = ops->vidioc_s_fmt_vid_out(file, fh, f); 813 break; 814 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 815 CLEAR_AFTER_FIELD(f, fmt.win); 816 if (ops->vidioc_s_fmt_vid_out_overlay) 817 ret = ops->vidioc_s_fmt_vid_out_overlay(file, 818 fh, f); 819 break; 820 case V4L2_BUF_TYPE_VBI_CAPTURE: 821 CLEAR_AFTER_FIELD(f, fmt.vbi); 822 if (ops->vidioc_s_fmt_vbi_cap) 823 ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f); 824 break; 825 case V4L2_BUF_TYPE_VBI_OUTPUT: 826 CLEAR_AFTER_FIELD(f, fmt.vbi); 827 if (ops->vidioc_s_fmt_vbi_out) 828 ret = ops->vidioc_s_fmt_vbi_out(file, fh, f); 829 break; 830 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 831 CLEAR_AFTER_FIELD(f, fmt.sliced); 832 if (ops->vidioc_s_fmt_sliced_vbi_cap) 833 ret = ops->vidioc_s_fmt_sliced_vbi_cap(file, 834 fh, f); 835 break; 836 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 837 CLEAR_AFTER_FIELD(f, fmt.sliced); 838 if (ops->vidioc_s_fmt_sliced_vbi_out) 839 ret = ops->vidioc_s_fmt_sliced_vbi_out(file, 840 fh, f); 841 break; 842 case V4L2_BUF_TYPE_PRIVATE: 843 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ 844 if (ops->vidioc_s_fmt_type_private) 845 ret = ops->vidioc_s_fmt_type_private(file, 846 fh, f); 847 break; 848 } 849 break; 850 } 851 case VIDIOC_TRY_FMT: 852 { 853 struct v4l2_format *f = (struct v4l2_format *)arg; 854 855 /* FIXME: Should be one dump per type */ 856 dbgarg(cmd, "type=%s\n", prt_names(f->type, 857 v4l2_type_names)); 858 switch (f->type) { 859 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 860 CLEAR_AFTER_FIELD(f, fmt.pix); 861 if (ops->vidioc_try_fmt_vid_cap) 862 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f); 863 if (!ret) 864 v4l_print_pix_fmt(vfd, &f->fmt.pix); 865 break; 866 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 867 CLEAR_AFTER_FIELD(f, fmt.win); 868 if (ops->vidioc_try_fmt_vid_overlay) 869 ret = ops->vidioc_try_fmt_vid_overlay(file, 870 fh, f); 871 break; 872 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 873 CLEAR_AFTER_FIELD(f, fmt.pix); 874 if (ops->vidioc_try_fmt_vid_out) 875 ret = ops->vidioc_try_fmt_vid_out(file, fh, f); 876 if (!ret) 877 v4l_print_pix_fmt(vfd, &f->fmt.pix); 878 break; 879 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 880 CLEAR_AFTER_FIELD(f, fmt.win); 881 if (ops->vidioc_try_fmt_vid_out_overlay) 882 ret = ops->vidioc_try_fmt_vid_out_overlay(file, 883 fh, f); 884 break; 885 case V4L2_BUF_TYPE_VBI_CAPTURE: 886 CLEAR_AFTER_FIELD(f, fmt.vbi); 887 if (ops->vidioc_try_fmt_vbi_cap) 888 ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f); 889 break; 890 case V4L2_BUF_TYPE_VBI_OUTPUT: 891 CLEAR_AFTER_FIELD(f, fmt.vbi); 892 if (ops->vidioc_try_fmt_vbi_out) 893 ret = ops->vidioc_try_fmt_vbi_out(file, fh, f); 894 break; 895 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 896 CLEAR_AFTER_FIELD(f, fmt.sliced); 897 if (ops->vidioc_try_fmt_sliced_vbi_cap) 898 ret = ops->vidioc_try_fmt_sliced_vbi_cap(file, 899 fh, f); 900 break; 901 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 902 CLEAR_AFTER_FIELD(f, fmt.sliced); 903 if (ops->vidioc_try_fmt_sliced_vbi_out) 904 ret = ops->vidioc_try_fmt_sliced_vbi_out(file, 905 fh, f); 906 break; 907 case V4L2_BUF_TYPE_PRIVATE: 908 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ 909 if (ops->vidioc_try_fmt_type_private) 910 ret = ops->vidioc_try_fmt_type_private(file, 911 fh, f); 912 break; 913 } 914 915 break; 916 } 917 /* FIXME: Those buf reqs could be handled here, 918 with some changes on videobuf to allow its header to be included at 919 videodev2.h or being merged at videodev2. 920 */ 921 case VIDIOC_REQBUFS: 922 { 923 struct v4l2_requestbuffers *p = arg; 924 925 if (!ops->vidioc_reqbufs) 926 break; 927 ret = check_fmt(ops, p->type); 928 if (ret) 929 break; 930 931 if (p->type < V4L2_BUF_TYPE_PRIVATE) 932 CLEAR_AFTER_FIELD(p, memory); 933 934 ret = ops->vidioc_reqbufs(file, fh, p); 935 dbgarg(cmd, "count=%d, type=%s, memory=%s\n", 936 p->count, 937 prt_names(p->type, v4l2_type_names), 938 prt_names(p->memory, v4l2_memory_names)); 939 break; 940 } 941 case VIDIOC_QUERYBUF: 942 { 943 struct v4l2_buffer *p = arg; 944 945 if (!ops->vidioc_querybuf) 946 break; 947 ret = check_fmt(ops, p->type); 948 if (ret) 949 break; 950 951 ret = ops->vidioc_querybuf(file, fh, p); 952 if (!ret) 953 dbgbuf(cmd, vfd, p); 954 break; 955 } 956 case VIDIOC_QBUF: 957 { 958 struct v4l2_buffer *p = arg; 959 960 if (!ops->vidioc_qbuf) 961 break; 962 ret = check_fmt(ops, p->type); 963 if (ret) 964 break; 965 966 ret = ops->vidioc_qbuf(file, fh, p); 967 if (!ret) 968 dbgbuf(cmd, vfd, p); 969 break; 970 } 971 case VIDIOC_DQBUF: 972 { 973 struct v4l2_buffer *p = arg; 974 975 if (!ops->vidioc_dqbuf) 976 break; 977 ret = check_fmt(ops, p->type); 978 if (ret) 979 break; 980 981 ret = ops->vidioc_dqbuf(file, fh, p); 982 if (!ret) 983 dbgbuf(cmd, vfd, p); 984 break; 985 } 986 case VIDIOC_OVERLAY: 987 { 988 int *i = arg; 989 990 if (!ops->vidioc_overlay) 991 break; 992 dbgarg(cmd, "value=%d\n", *i); 993 ret = ops->vidioc_overlay(file, fh, *i); 994 break; 995 } 996 case VIDIOC_G_FBUF: 997 { 998 struct v4l2_framebuffer *p = arg; 999 1000 if (!ops->vidioc_g_fbuf) 1001 break; 1002 ret = ops->vidioc_g_fbuf(file, fh, arg); 1003 if (!ret) { 1004 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", 1005 p->capability, p->flags, 1006 (unsigned long)p->base); 1007 v4l_print_pix_fmt(vfd, &p->fmt); 1008 } 1009 break; 1010 } 1011 case VIDIOC_S_FBUF: 1012 { 1013 struct v4l2_framebuffer *p = arg; 1014 1015 if (!ops->vidioc_s_fbuf) 1016 break; 1017 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", 1018 p->capability, p->flags, (unsigned long)p->base); 1019 v4l_print_pix_fmt(vfd, &p->fmt); 1020 ret = ops->vidioc_s_fbuf(file, fh, arg); 1021 break; 1022 } 1023 case VIDIOC_STREAMON: 1024 { 1025 enum v4l2_buf_type i = *(int *)arg; 1026 1027 if (!ops->vidioc_streamon) 1028 break; 1029 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); 1030 ret = ops->vidioc_streamon(file, fh, i); 1031 break; 1032 } 1033 case VIDIOC_STREAMOFF: 1034 { 1035 enum v4l2_buf_type i = *(int *)arg; 1036 1037 if (!ops->vidioc_streamoff) 1038 break; 1039 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); 1040 ret = ops->vidioc_streamoff(file, fh, i); 1041 break; 1042 } 1043 /* ---------- tv norms ---------- */ 1044 case VIDIOC_ENUMSTD: 1045 { 1046 struct v4l2_standard *p = arg; 1047 v4l2_std_id id = vfd->tvnorms, curr_id = 0; 1048 unsigned int index = p->index, i, j = 0; 1049 const char *descr = ""; 1050 1051 /* Return norm array in a canonical way */ 1052 for (i = 0; i <= index && id; i++) { 1053 /* last std value in the standards array is 0, so this 1054 while always ends there since (id & 0) == 0. */ 1055 while ((id & standards[j].std) != standards[j].std) 1056 j++; 1057 curr_id = standards[j].std; 1058 descr = standards[j].descr; 1059 j++; 1060 if (curr_id == 0) 1061 break; 1062 if (curr_id != V4L2_STD_PAL && 1063 curr_id != V4L2_STD_SECAM && 1064 curr_id != V4L2_STD_NTSC) 1065 id &= ~curr_id; 1066 } 1067 if (i <= index) 1068 return -EINVAL; 1069 1070 v4l2_video_std_construct(p, curr_id, descr); 1071 1072 dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, " 1073 "framelines=%d\n", p->index, 1074 (unsigned long long)p->id, p->name, 1075 p->frameperiod.numerator, 1076 p->frameperiod.denominator, 1077 p->framelines); 1078 1079 ret = 0; 1080 break; 1081 } 1082 case VIDIOC_G_STD: 1083 { 1084 v4l2_std_id *id = arg; 1085 1086 ret = 0; 1087 /* Calls the specific handler */ 1088 if (ops->vidioc_g_std) 1089 ret = ops->vidioc_g_std(file, fh, id); 1090 else if (vfd->current_norm) 1091 *id = vfd->current_norm; 1092 else 1093 ret = -EINVAL; 1094 1095 if (!ret) 1096 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id); 1097 break; 1098 } 1099 case VIDIOC_S_STD: 1100 { 1101 v4l2_std_id *id = arg, norm; 1102 1103 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id); 1104 1105 norm = (*id) & vfd->tvnorms; 1106 if (vfd->tvnorms && !norm) /* Check if std is supported */ 1107 break; 1108 1109 /* Calls the specific handler */ 1110 if (ops->vidioc_s_std) 1111 ret = ops->vidioc_s_std(file, fh, &norm); 1112 else 1113 ret = -EINVAL; 1114 1115 /* Updates standard information */ 1116 if (ret >= 0) 1117 vfd->current_norm = norm; 1118 break; 1119 } 1120 case VIDIOC_QUERYSTD: 1121 { 1122 v4l2_std_id *p = arg; 1123 1124 if (!ops->vidioc_querystd) 1125 break; 1126 ret = ops->vidioc_querystd(file, fh, arg); 1127 if (!ret) 1128 dbgarg(cmd, "detected std=%08Lx\n", 1129 (unsigned long long)*p); 1130 break; 1131 } 1132 /* ------ input switching ---------- */ 1133 /* FIXME: Inputs can be handled inside videodev2 */ 1134 case VIDIOC_ENUMINPUT: 1135 { 1136 struct v4l2_input *p = arg; 1137 1138 if (!ops->vidioc_enum_input) 1139 break; 1140 1141 ret = ops->vidioc_enum_input(file, fh, p); 1142 if (!ret) 1143 dbgarg(cmd, "index=%d, name=%s, type=%d, " 1144 "audioset=%d, " 1145 "tuner=%d, std=%08Lx, status=%d\n", 1146 p->index, p->name, p->type, p->audioset, 1147 p->tuner, 1148 (unsigned long long)p->std, 1149 p->status); 1150 break; 1151 } 1152 case VIDIOC_G_INPUT: 1153 { 1154 unsigned int *i = arg; 1155 1156 if (!ops->vidioc_g_input) 1157 break; 1158 ret = ops->vidioc_g_input(file, fh, i); 1159 if (!ret) 1160 dbgarg(cmd, "value=%d\n", *i); 1161 break; 1162 } 1163 case VIDIOC_S_INPUT: 1164 { 1165 unsigned int *i = arg; 1166 1167 if (!ops->vidioc_s_input) 1168 break; 1169 dbgarg(cmd, "value=%d\n", *i); 1170 ret = ops->vidioc_s_input(file, fh, *i); 1171 break; 1172 } 1173 1174 /* ------ output switching ---------- */ 1175 case VIDIOC_ENUMOUTPUT: 1176 { 1177 struct v4l2_output *p = arg; 1178 1179 if (!ops->vidioc_enum_output) 1180 break; 1181 1182 ret = ops->vidioc_enum_output(file, fh, p); 1183 if (!ret) 1184 dbgarg(cmd, "index=%d, name=%s, type=%d, " 1185 "audioset=0x%x, " 1186 "modulator=%d, std=0x%08Lx\n", 1187 p->index, p->name, p->type, p->audioset, 1188 p->modulator, (unsigned long long)p->std); 1189 break; 1190 } 1191 case VIDIOC_G_OUTPUT: 1192 { 1193 unsigned int *i = arg; 1194 1195 if (!ops->vidioc_g_output) 1196 break; 1197 ret = ops->vidioc_g_output(file, fh, i); 1198 if (!ret) 1199 dbgarg(cmd, "value=%d\n", *i); 1200 break; 1201 } 1202 case VIDIOC_S_OUTPUT: 1203 { 1204 unsigned int *i = arg; 1205 1206 if (!ops->vidioc_s_output) 1207 break; 1208 dbgarg(cmd, "value=%d\n", *i); 1209 ret = ops->vidioc_s_output(file, fh, *i); 1210 break; 1211 } 1212 1213 /* --- controls ---------------------------------------------- */ 1214 case VIDIOC_QUERYCTRL: 1215 { 1216 struct v4l2_queryctrl *p = arg; 1217 1218 if (!ops->vidioc_queryctrl) 1219 break; 1220 ret = ops->vidioc_queryctrl(file, fh, p); 1221 if (!ret) 1222 dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, " 1223 "step=%d, default=%d, flags=0x%08x\n", 1224 p->id, p->type, p->name, 1225 p->minimum, p->maximum, 1226 p->step, p->default_value, p->flags); 1227 else 1228 dbgarg(cmd, "id=0x%x\n", p->id); 1229 break; 1230 } 1231 case VIDIOC_G_CTRL: 1232 { 1233 struct v4l2_control *p = arg; 1234 1235 if (ops->vidioc_g_ctrl) 1236 ret = ops->vidioc_g_ctrl(file, fh, p); 1237 else if (ops->vidioc_g_ext_ctrls) { 1238 struct v4l2_ext_controls ctrls; 1239 struct v4l2_ext_control ctrl; 1240 1241 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); 1242 ctrls.count = 1; 1243 ctrls.controls = &ctrl; 1244 ctrl.id = p->id; 1245 ctrl.value = p->value; 1246 if (check_ext_ctrls(&ctrls, 1)) { 1247 ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls); 1248 if (ret == 0) 1249 p->value = ctrl.value; 1250 } 1251 } else 1252 break; 1253 if (!ret) 1254 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); 1255 else 1256 dbgarg(cmd, "id=0x%x\n", p->id); 1257 break; 1258 } 1259 case VIDIOC_S_CTRL: 1260 { 1261 struct v4l2_control *p = arg; 1262 struct v4l2_ext_controls ctrls; 1263 struct v4l2_ext_control ctrl; 1264 1265 if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls) 1266 break; 1267 1268 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); 1269 1270 if (ops->vidioc_s_ctrl) { 1271 ret = ops->vidioc_s_ctrl(file, fh, p); 1272 break; 1273 } 1274 if (!ops->vidioc_s_ext_ctrls) 1275 break; 1276 1277 ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); 1278 ctrls.count = 1; 1279 ctrls.controls = &ctrl; 1280 ctrl.id = p->id; 1281 ctrl.value = p->value; 1282 if (check_ext_ctrls(&ctrls, 1)) 1283 ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls); 1284 break; 1285 } 1286 case VIDIOC_G_EXT_CTRLS: 1287 { 1288 struct v4l2_ext_controls *p = arg; 1289 1290 p->error_idx = p->count; 1291 if (!ops->vidioc_g_ext_ctrls) 1292 break; 1293 if (check_ext_ctrls(p, 0)) 1294 ret = ops->vidioc_g_ext_ctrls(file, fh, p); 1295 v4l_print_ext_ctrls(cmd, vfd, p, !ret); 1296 break; 1297 } 1298 case VIDIOC_S_EXT_CTRLS: 1299 { 1300 struct v4l2_ext_controls *p = arg; 1301 1302 p->error_idx = p->count; 1303 if (!ops->vidioc_s_ext_ctrls) 1304 break; 1305 v4l_print_ext_ctrls(cmd, vfd, p, 1); 1306 if (check_ext_ctrls(p, 0)) 1307 ret = ops->vidioc_s_ext_ctrls(file, fh, p); 1308 break; 1309 } 1310 case VIDIOC_TRY_EXT_CTRLS: 1311 { 1312 struct v4l2_ext_controls *p = arg; 1313 1314 p->error_idx = p->count; 1315 if (!ops->vidioc_try_ext_ctrls) 1316 break; 1317 v4l_print_ext_ctrls(cmd, vfd, p, 1); 1318 if (check_ext_ctrls(p, 0)) 1319 ret = ops->vidioc_try_ext_ctrls(file, fh, p); 1320 break; 1321 } 1322 case VIDIOC_QUERYMENU: 1323 { 1324 struct v4l2_querymenu *p = arg; 1325 1326 if (!ops->vidioc_querymenu) 1327 break; 1328 ret = ops->vidioc_querymenu(file, fh, p); 1329 if (!ret) 1330 dbgarg(cmd, "id=0x%x, index=%d, name=%s\n", 1331 p->id, p->index, p->name); 1332 else 1333 dbgarg(cmd, "id=0x%x, index=%d\n", 1334 p->id, p->index); 1335 break; 1336 } 1337 /* --- audio ---------------------------------------------- */ 1338 case VIDIOC_ENUMAUDIO: 1339 { 1340 struct v4l2_audio *p = arg; 1341 1342 if (!ops->vidioc_enumaudio) 1343 break; 1344 ret = ops->vidioc_enumaudio(file, fh, p); 1345 if (!ret) 1346 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " 1347 "mode=0x%x\n", p->index, p->name, 1348 p->capability, p->mode); 1349 else 1350 dbgarg(cmd, "index=%d\n", p->index); 1351 break; 1352 } 1353 case VIDIOC_G_AUDIO: 1354 { 1355 struct v4l2_audio *p = arg; 1356 1357 if (!ops->vidioc_g_audio) 1358 break; 1359 1360 ret = ops->vidioc_g_audio(file, fh, p); 1361 if (!ret) 1362 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " 1363 "mode=0x%x\n", p->index, 1364 p->name, p->capability, p->mode); 1365 else 1366 dbgarg(cmd, "index=%d\n", p->index); 1367 break; 1368 } 1369 case VIDIOC_S_AUDIO: 1370 { 1371 struct v4l2_audio *p = arg; 1372 1373 if (!ops->vidioc_s_audio) 1374 break; 1375 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " 1376 "mode=0x%x\n", p->index, p->name, 1377 p->capability, p->mode); 1378 ret = ops->vidioc_s_audio(file, fh, p); 1379 break; 1380 } 1381 case VIDIOC_ENUMAUDOUT: 1382 { 1383 struct v4l2_audioout *p = arg; 1384 1385 if (!ops->vidioc_enumaudout) 1386 break; 1387 dbgarg(cmd, "Enum for index=%d\n", p->index); 1388 ret = ops->vidioc_enumaudout(file, fh, p); 1389 if (!ret) 1390 dbgarg2("index=%d, name=%s, capability=%d, " 1391 "mode=%d\n", p->index, p->name, 1392 p->capability, p->mode); 1393 break; 1394 } 1395 case VIDIOC_G_AUDOUT: 1396 { 1397 struct v4l2_audioout *p = arg; 1398 1399 if (!ops->vidioc_g_audout) 1400 break; 1401 1402 ret = ops->vidioc_g_audout(file, fh, p); 1403 if (!ret) 1404 dbgarg2("index=%d, name=%s, capability=%d, " 1405 "mode=%d\n", p->index, p->name, 1406 p->capability, p->mode); 1407 break; 1408 } 1409 case VIDIOC_S_AUDOUT: 1410 { 1411 struct v4l2_audioout *p = arg; 1412 1413 if (!ops->vidioc_s_audout) 1414 break; 1415 dbgarg(cmd, "index=%d, name=%s, capability=%d, " 1416 "mode=%d\n", p->index, p->name, 1417 p->capability, p->mode); 1418 1419 ret = ops->vidioc_s_audout(file, fh, p); 1420 break; 1421 } 1422 case VIDIOC_G_MODULATOR: 1423 { 1424 struct v4l2_modulator *p = arg; 1425 1426 if (!ops->vidioc_g_modulator) 1427 break; 1428 ret = ops->vidioc_g_modulator(file, fh, p); 1429 if (!ret) 1430 dbgarg(cmd, "index=%d, name=%s, " 1431 "capability=%d, rangelow=%d," 1432 " rangehigh=%d, txsubchans=%d\n", 1433 p->index, p->name, p->capability, 1434 p->rangelow, p->rangehigh, 1435 p->txsubchans); 1436 break; 1437 } 1438 case VIDIOC_S_MODULATOR: 1439 { 1440 struct v4l2_modulator *p = arg; 1441 1442 if (!ops->vidioc_s_modulator) 1443 break; 1444 dbgarg(cmd, "index=%d, name=%s, capability=%d, " 1445 "rangelow=%d, rangehigh=%d, txsubchans=%d\n", 1446 p->index, p->name, p->capability, p->rangelow, 1447 p->rangehigh, p->txsubchans); 1448 ret = ops->vidioc_s_modulator(file, fh, p); 1449 break; 1450 } 1451 case VIDIOC_G_CROP: 1452 { 1453 struct v4l2_crop *p = arg; 1454 1455 if (!ops->vidioc_g_crop) 1456 break; 1457 1458 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1459 ret = ops->vidioc_g_crop(file, fh, p); 1460 if (!ret) 1461 dbgrect(vfd, "", &p->c); 1462 break; 1463 } 1464 case VIDIOC_S_CROP: 1465 { 1466 struct v4l2_crop *p = arg; 1467 1468 if (!ops->vidioc_s_crop) 1469 break; 1470 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1471 dbgrect(vfd, "", &p->c); 1472 ret = ops->vidioc_s_crop(file, fh, p); 1473 break; 1474 } 1475 case VIDIOC_CROPCAP: 1476 { 1477 struct v4l2_cropcap *p = arg; 1478 1479 /*FIXME: Should also show v4l2_fract pixelaspect */ 1480 if (!ops->vidioc_cropcap) 1481 break; 1482 1483 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1484 ret = ops->vidioc_cropcap(file, fh, p); 1485 if (!ret) { 1486 dbgrect(vfd, "bounds ", &p->bounds); 1487 dbgrect(vfd, "defrect ", &p->defrect); 1488 } 1489 break; 1490 } 1491 case VIDIOC_G_JPEGCOMP: 1492 { 1493 struct v4l2_jpegcompression *p = arg; 1494 1495 if (!ops->vidioc_g_jpegcomp) 1496 break; 1497 1498 ret = ops->vidioc_g_jpegcomp(file, fh, p); 1499 if (!ret) 1500 dbgarg(cmd, "quality=%d, APPn=%d, " 1501 "APP_len=%d, COM_len=%d, " 1502 "jpeg_markers=%d\n", 1503 p->quality, p->APPn, p->APP_len, 1504 p->COM_len, p->jpeg_markers); 1505 break; 1506 } 1507 case VIDIOC_S_JPEGCOMP: 1508 { 1509 struct v4l2_jpegcompression *p = arg; 1510 1511 if (!ops->vidioc_g_jpegcomp) 1512 break; 1513 dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, " 1514 "COM_len=%d, jpeg_markers=%d\n", 1515 p->quality, p->APPn, p->APP_len, 1516 p->COM_len, p->jpeg_markers); 1517 ret = ops->vidioc_s_jpegcomp(file, fh, p); 1518 break; 1519 } 1520 case VIDIOC_G_ENC_INDEX: 1521 { 1522 struct v4l2_enc_idx *p = arg; 1523 1524 if (!ops->vidioc_g_enc_index) 1525 break; 1526 ret = ops->vidioc_g_enc_index(file, fh, p); 1527 if (!ret) 1528 dbgarg(cmd, "entries=%d, entries_cap=%d\n", 1529 p->entries, p->entries_cap); 1530 break; 1531 } 1532 case VIDIOC_ENCODER_CMD: 1533 { 1534 struct v4l2_encoder_cmd *p = arg; 1535 1536 if (!ops->vidioc_encoder_cmd) 1537 break; 1538 ret = ops->vidioc_encoder_cmd(file, fh, p); 1539 if (!ret) 1540 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); 1541 break; 1542 } 1543 case VIDIOC_TRY_ENCODER_CMD: 1544 { 1545 struct v4l2_encoder_cmd *p = arg; 1546 1547 if (!ops->vidioc_try_encoder_cmd) 1548 break; 1549 ret = ops->vidioc_try_encoder_cmd(file, fh, p); 1550 if (!ret) 1551 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); 1552 break; 1553 } 1554 case VIDIOC_G_PARM: 1555 { 1556 struct v4l2_streamparm *p = arg; 1557 1558 if (ops->vidioc_g_parm) { 1559 ret = check_fmt(ops, p->type); 1560 if (ret) 1561 break; 1562 ret = ops->vidioc_g_parm(file, fh, p); 1563 } else { 1564 v4l2_std_id std = vfd->current_norm; 1565 1566 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1567 return -EINVAL; 1568 1569 ret = 0; 1570 if (ops->vidioc_g_std) 1571 ret = ops->vidioc_g_std(file, fh, &std); 1572 else if (std == 0) 1573 ret = -EINVAL; 1574 if (ret == 0) 1575 v4l2_video_std_frame_period(std, 1576 &p->parm.capture.timeperframe); 1577 } 1578 1579 dbgarg(cmd, "type=%d\n", p->type); 1580 break; 1581 } 1582 case VIDIOC_S_PARM: 1583 { 1584 struct v4l2_streamparm *p = arg; 1585 1586 if (!ops->vidioc_s_parm) 1587 break; 1588 ret = check_fmt(ops, p->type); 1589 if (ret) 1590 break; 1591 1592 dbgarg(cmd, "type=%d\n", p->type); 1593 ret = ops->vidioc_s_parm(file, fh, p); 1594 break; 1595 } 1596 case VIDIOC_G_TUNER: 1597 { 1598 struct v4l2_tuner *p = arg; 1599 1600 if (!ops->vidioc_g_tuner) 1601 break; 1602 1603 ret = ops->vidioc_g_tuner(file, fh, p); 1604 if (!ret) 1605 dbgarg(cmd, "index=%d, name=%s, type=%d, " 1606 "capability=0x%x, rangelow=%d, " 1607 "rangehigh=%d, signal=%d, afc=%d, " 1608 "rxsubchans=0x%x, audmode=%d\n", 1609 p->index, p->name, p->type, 1610 p->capability, p->rangelow, 1611 p->rangehigh, p->signal, p->afc, 1612 p->rxsubchans, p->audmode); 1613 break; 1614 } 1615 case VIDIOC_S_TUNER: 1616 { 1617 struct v4l2_tuner *p = arg; 1618 1619 if (!ops->vidioc_s_tuner) 1620 break; 1621 dbgarg(cmd, "index=%d, name=%s, type=%d, " 1622 "capability=0x%x, rangelow=%d, " 1623 "rangehigh=%d, signal=%d, afc=%d, " 1624 "rxsubchans=0x%x, audmode=%d\n", 1625 p->index, p->name, p->type, 1626 p->capability, p->rangelow, 1627 p->rangehigh, p->signal, p->afc, 1628 p->rxsubchans, p->audmode); 1629 ret = ops->vidioc_s_tuner(file, fh, p); 1630 break; 1631 } 1632 case VIDIOC_G_FREQUENCY: 1633 { 1634 struct v4l2_frequency *p = arg; 1635 1636 if (!ops->vidioc_g_frequency) 1637 break; 1638 1639 ret = ops->vidioc_g_frequency(file, fh, p); 1640 if (!ret) 1641 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", 1642 p->tuner, p->type, p->frequency); 1643 break; 1644 } 1645 case VIDIOC_S_FREQUENCY: 1646 { 1647 struct v4l2_frequency *p = arg; 1648 1649 if (!ops->vidioc_s_frequency) 1650 break; 1651 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", 1652 p->tuner, p->type, p->frequency); 1653 ret = ops->vidioc_s_frequency(file, fh, p); 1654 break; 1655 } 1656 case VIDIOC_G_SLICED_VBI_CAP: 1657 { 1658 struct v4l2_sliced_vbi_cap *p = arg; 1659 1660 if (!ops->vidioc_g_sliced_vbi_cap) 1661 break; 1662 1663 /* Clear up to type, everything after type is zerod already */ 1664 memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); 1665 1666 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); 1667 ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p); 1668 if (!ret) 1669 dbgarg2("service_set=%d\n", p->service_set); 1670 break; 1671 } 1672 case VIDIOC_LOG_STATUS: 1673 { 1674 if (!ops->vidioc_log_status) 1675 break; 1676 ret = ops->vidioc_log_status(file, fh); 1677 break; 1678 } 1679#ifdef CONFIG_VIDEO_ADV_DEBUG 1680 case VIDIOC_DBG_G_REGISTER: 1681 { 1682 struct v4l2_dbg_register *p = arg; 1683 1684 if (!capable(CAP_SYS_ADMIN)) 1685 ret = -EPERM; 1686 else if (ops->vidioc_g_register) 1687 ret = ops->vidioc_g_register(file, fh, p); 1688 break; 1689 } 1690 case VIDIOC_DBG_S_REGISTER: 1691 { 1692 struct v4l2_dbg_register *p = arg; 1693 1694 if (!capable(CAP_SYS_ADMIN)) 1695 ret = -EPERM; 1696 else if (ops->vidioc_s_register) 1697 ret = ops->vidioc_s_register(file, fh, p); 1698 break; 1699 } 1700#endif 1701 case VIDIOC_DBG_G_CHIP_IDENT: 1702 { 1703 struct v4l2_dbg_chip_ident *p = arg; 1704 1705 if (!ops->vidioc_g_chip_ident) 1706 break; 1707 p->ident = V4L2_IDENT_NONE; 1708 p->revision = 0; 1709 ret = ops->vidioc_g_chip_ident(file, fh, p); 1710 if (!ret) 1711 dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); 1712 break; 1713 } 1714 case VIDIOC_S_HW_FREQ_SEEK: 1715 { 1716 struct v4l2_hw_freq_seek *p = arg; 1717 1718 if (!ops->vidioc_s_hw_freq_seek) 1719 break; 1720 dbgarg(cmd, 1721 "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n", 1722 p->tuner, p->type, p->seek_upward, p->wrap_around); 1723 ret = ops->vidioc_s_hw_freq_seek(file, fh, p); 1724 break; 1725 } 1726 case VIDIOC_ENUM_FRAMESIZES: 1727 { 1728 struct v4l2_frmsizeenum *p = arg; 1729 1730 if (!ops->vidioc_enum_framesizes) 1731 break; 1732 1733 ret = ops->vidioc_enum_framesizes(file, fh, p); 1734 dbgarg(cmd, 1735 "index=%d, pixelformat=%c%c%c%c, type=%d ", 1736 p->index, 1737 (p->pixel_format & 0xff), 1738 (p->pixel_format >> 8) & 0xff, 1739 (p->pixel_format >> 16) & 0xff, 1740 (p->pixel_format >> 24) & 0xff, 1741 p->type); 1742 switch (p->type) { 1743 case V4L2_FRMSIZE_TYPE_DISCRETE: 1744 dbgarg3("width = %d, height=%d\n", 1745 p->discrete.width, p->discrete.height); 1746 break; 1747 case V4L2_FRMSIZE_TYPE_STEPWISE: 1748 dbgarg3("min %dx%d, max %dx%d, step %dx%d\n", 1749 p->stepwise.min_width, p->stepwise.min_height, 1750 p->stepwise.step_width, p->stepwise.step_height, 1751 p->stepwise.max_width, p->stepwise.max_height); 1752 break; 1753 case V4L2_FRMSIZE_TYPE_CONTINUOUS: 1754 dbgarg3("continuous\n"); 1755 break; 1756 default: 1757 dbgarg3("- Unknown type!\n"); 1758 } 1759 1760 break; 1761 } 1762 case VIDIOC_ENUM_FRAMEINTERVALS: 1763 { 1764 struct v4l2_frmivalenum *p = arg; 1765 1766 if (!ops->vidioc_enum_frameintervals) 1767 break; 1768 1769 ret = ops->vidioc_enum_frameintervals(file, fh, p); 1770 dbgarg(cmd, 1771 "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ", 1772 p->index, p->pixel_format, 1773 p->width, p->height, p->type); 1774 switch (p->type) { 1775 case V4L2_FRMIVAL_TYPE_DISCRETE: 1776 dbgarg2("fps=%d/%d\n", 1777 p->discrete.numerator, 1778 p->discrete.denominator); 1779 break; 1780 case V4L2_FRMIVAL_TYPE_STEPWISE: 1781 dbgarg2("min=%d/%d, max=%d/%d, step=%d/%d\n", 1782 p->stepwise.min.numerator, 1783 p->stepwise.min.denominator, 1784 p->stepwise.max.numerator, 1785 p->stepwise.max.denominator, 1786 p->stepwise.step.numerator, 1787 p->stepwise.step.denominator); 1788 break; 1789 case V4L2_FRMIVAL_TYPE_CONTINUOUS: 1790 dbgarg2("continuous\n"); 1791 break; 1792 default: 1793 dbgarg2("- Unknown type!\n"); 1794 } 1795 break; 1796 } 1797 1798 default: 1799 { 1800 if (!ops->vidioc_default) 1801 break; 1802 ret = ops->vidioc_default(file, fh, cmd, arg); 1803 break; 1804 } 1805 } /* switch */ 1806 1807 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { 1808 if (ret < 0) { 1809 v4l_print_ioctl(vfd->name, cmd); 1810 printk(KERN_CONT " error %ld\n", ret); 1811 } 1812 } 1813 1814 return ret; 1815} 1816 1817/* In some cases, only a few fields are used as input, i.e. when the app sets 1818 * "index" and then the driver fills in the rest of the structure for the thing 1819 * with that index. We only need to copy up the first non-input field. */ 1820static unsigned long cmd_input_size(unsigned int cmd) 1821{ 1822 /* Size of structure up to and including 'field' */ 1823#define CMDINSIZE(cmd, type, field) \ 1824 case VIDIOC_##cmd: \ 1825 return offsetof(struct v4l2_##type, field) + \ 1826 sizeof(((struct v4l2_##type *)0)->field); 1827 1828 switch (cmd) { 1829 CMDINSIZE(ENUM_FMT, fmtdesc, type); 1830 CMDINSIZE(G_FMT, format, type); 1831 CMDINSIZE(QUERYBUF, buffer, type); 1832 CMDINSIZE(G_PARM, streamparm, type); 1833 CMDINSIZE(ENUMSTD, standard, index); 1834 CMDINSIZE(ENUMINPUT, input, index); 1835 CMDINSIZE(G_CTRL, control, id); 1836 CMDINSIZE(G_TUNER, tuner, index); 1837 CMDINSIZE(QUERYCTRL, queryctrl, id); 1838 CMDINSIZE(QUERYMENU, querymenu, index); 1839 CMDINSIZE(ENUMOUTPUT, output, index); 1840 CMDINSIZE(G_MODULATOR, modulator, index); 1841 CMDINSIZE(G_FREQUENCY, frequency, tuner); 1842 CMDINSIZE(CROPCAP, cropcap, type); 1843 CMDINSIZE(G_CROP, crop, type); 1844 CMDINSIZE(ENUMAUDIO, audio, index); 1845 CMDINSIZE(ENUMAUDOUT, audioout, index); 1846 CMDINSIZE(ENCODER_CMD, encoder_cmd, flags); 1847 CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags); 1848 CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type); 1849 CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format); 1850 CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height); 1851 default: 1852 return _IOC_SIZE(cmd); 1853 } 1854} 1855 1856long video_ioctl2(struct file *file, 1857 unsigned int cmd, unsigned long arg) 1858{ 1859 char sbuf[128]; 1860 void *mbuf = NULL; 1861 void *parg = NULL; 1862 long err = -EINVAL; 1863 int is_ext_ctrl; 1864 size_t ctrls_size = 0; 1865 void __user *user_ptr = NULL; 1866 1867#ifdef __OLD_VIDIOC_ 1868 cmd = video_fix_command(cmd); 1869#endif 1870 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || 1871 cmd == VIDIOC_TRY_EXT_CTRLS); 1872 1873 /* Copy arguments into temp kernel buffer */ 1874 if (_IOC_DIR(cmd) != _IOC_NONE) { 1875 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { 1876 parg = sbuf; 1877 } else { 1878 /* too big to allocate from stack */ 1879 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); 1880 if (NULL == mbuf) 1881 return -ENOMEM; 1882 parg = mbuf; 1883 } 1884 1885 err = -EFAULT; 1886 if (_IOC_DIR(cmd) & _IOC_WRITE) { 1887 unsigned long n = cmd_input_size(cmd); 1888 1889 if (copy_from_user(parg, (void __user *)arg, n)) 1890 goto out; 1891 1892 /* zero out anything we don't copy from userspace */ 1893 if (n < _IOC_SIZE(cmd)) 1894 memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n); 1895 } else { 1896 /* read-only ioctl */ 1897 memset(parg, 0, _IOC_SIZE(cmd)); 1898 } 1899 } 1900 1901 if (is_ext_ctrl) { 1902 struct v4l2_ext_controls *p = parg; 1903 1904 /* In case of an error, tell the caller that it wasn't 1905 a specific control that caused it. */ 1906 p->error_idx = p->count; 1907 user_ptr = (void __user *)p->controls; 1908 if (p->count) { 1909 ctrls_size = sizeof(struct v4l2_ext_control) * p->count; 1910 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ 1911 mbuf = kmalloc(ctrls_size, GFP_KERNEL); 1912 err = -ENOMEM; 1913 if (NULL == mbuf) 1914 goto out_ext_ctrl; 1915 err = -EFAULT; 1916 if (copy_from_user(mbuf, user_ptr, ctrls_size)) 1917 goto out_ext_ctrl; 1918 p->controls = mbuf; 1919 } 1920 } 1921 1922 /* Handles IOCTL */ 1923 err = __video_do_ioctl(file, cmd, parg); 1924 if (err == -ENOIOCTLCMD) 1925 err = -EINVAL; 1926 if (is_ext_ctrl) { 1927 struct v4l2_ext_controls *p = parg; 1928 1929 p->controls = (void *)user_ptr; 1930 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) 1931 err = -EFAULT; 1932 goto out_ext_ctrl; 1933 } 1934 if (err < 0) 1935 goto out; 1936 1937out_ext_ctrl: 1938 /* Copy results into user buffer */ 1939 switch (_IOC_DIR(cmd)) { 1940 case _IOC_READ: 1941 case (_IOC_WRITE | _IOC_READ): 1942 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) 1943 err = -EFAULT; 1944 break; 1945 } 1946 1947out: 1948 kfree(mbuf); 1949 return err; 1950} 1951EXPORT_SYMBOL(video_ioctl2);