r5u870

Ricoh R5U870 Linux Driver
git clone https://logand.com/git/r5u870.git/
Log | Files | Refs | README | LICENSE

usbcam_fops.c (31610B)


      1 /*
      2  * USBCAM abstraction library for USB webcam drivers
      3  * Version 0.11.1
      4  *
      5  * Copyright (c) 2007 Sam Revitch <samr7 cs washington edu>
      6  * Copyright (c) 2008 Alexander Hixon <hixon.alexander@mediati.org>
      7  *
      8  * This program is free software; you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation; either version 2, or (at your option)
     11  * any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
     21  */
     22 
     23 #include "usbcam_priv.h"
     24 #include "media/v4l2-ioctl.h"
     25 
     26 /*
     27  * This file contains the file_operations implementation
     28  *
     29  * TODO LIST:
     30  * - Add debug tracing to more ioctl paths
     31  */
     32 
     33 /* HELPER FOR V4L1 COMPAT OPS */
     34 
     35 const static unsigned int palette2pixelformat[] = {
     36 	[VIDEO_PALETTE_GREY]    = V4L2_PIX_FMT_GREY,
     37 	[VIDEO_PALETTE_RGB555]  = V4L2_PIX_FMT_RGB555,
     38 	[VIDEO_PALETTE_RGB565]  = V4L2_PIX_FMT_RGB565,
     39 	[VIDEO_PALETTE_RGB24]   = V4L2_PIX_FMT_BGR24,
     40 	[VIDEO_PALETTE_RGB32]   = V4L2_PIX_FMT_BGR32,
     41 	/* yuv packed pixel */
     42 	[VIDEO_PALETTE_YUYV]    = V4L2_PIX_FMT_YUYV,
     43 	[VIDEO_PALETTE_YUV422]  = V4L2_PIX_FMT_YUYV,
     44 	[VIDEO_PALETTE_UYVY]    = V4L2_PIX_FMT_UYVY,
     45 	/* yuv planar */
     46 	[VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410,
     47 	[VIDEO_PALETTE_YUV420]  = V4L2_PIX_FMT_YUV420,
     48 	[VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420,
     49 	[VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P,
     50 	[VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
     51 };
     52 
     53 const static char *v4l_ioctl_names[] = {
     54 	"UNKNOWN",
     55 	"VIDIOCGCAP",
     56 	"VIDIOCGCHAN",
     57 	"VIDIOCSCHAN",
     58 	"VIDIOCGTUNER",
     59 	"VIDIOCSTUNER",
     60 	"VIDIOCGPICT",
     61 	"VIDIOCSPICT",
     62 	"VIDIOCCAPTURE",
     63 	"VIDIOCGWIN",
     64 	"VIDIOCSWIN",
     65 	"VIDIOCGFBUF",
     66 	"VIDIOCSFBUF",
     67 	"VIDIOCKEY",
     68 	"VIDIOCGFREQ",
     69 	"VIDIOCSFREQ",
     70 	"VIDIOCGAUDIO",
     71 	"VIDIOCSAUDIO",
     72 	"VIDIOCSYNC",
     73 	"VIDIOCMCAPTURE",
     74 	"VIDIOCGMBUF",
     75 	"VIDIOCGUNIT",
     76 	"VIDIOCGCAPTURE",
     77 	"VIDIOCSCAPTURE",
     78 	"VIDIOCSPLAYMODE",
     79 	"VIDIOCSWRITEMODE",
     80 	"VIDIOCGPLAYINFO",
     81 	"VIDIOCSMICROCODE",
     82 	"VIDIOCGVBIFMT",
     83 	"VIDIOCSVBIFMT",
     84 };
     85 
     86 spinlock_t slock;
     87 
     88 static unsigned int __pure
     89 palette_to_pixelformat(unsigned int palette)
     90 {
     91 	if (palette < ARRAY_SIZE(palette2pixelformat))
     92 		return palette2pixelformat[palette];
     93 	else
     94 		return 0;
     95 }
     96 
     97 static int poll_one(struct file *file)
     98 {
     99 	int retval = 1;
    100 	poll_table *table;
    101 	struct poll_wqueues pwq;
    102 
    103 	poll_initwait(&pwq);
    104 	table = &pwq.pt;
    105 	for (;;) {
    106 		int mask;
    107 		set_current_state(TASK_INTERRUPTIBLE);
    108 		mask = file->f_op->poll(file, table);
    109 		if (mask & POLLIN)
    110 			break;
    111 		table = NULL;
    112 		if (signal_pending(current)) {
    113 			retval = -ERESTARTSYS;
    114 			break;
    115 		}
    116 		schedule();
    117 	}
    118 	set_current_state(TASK_RUNNING);
    119 	poll_freewait(&pwq);
    120 	return retval;
    121 }
    122 
    123 /*
    124  * V4L file_operations callout implementations
    125  */
    126 
    127 static int usbcam_v4l_open(struct inode *inode, struct file *filp)
    128 {
    129 	struct usbcam_dev *udp;
    130 	struct usbcam_fh *ufp;
    131 	int autopm_ref = 0;
    132 	int work_ref = 0;
    133 	int res = 0;
    134 
    135 	/* The usbcam_dev is referenced by the videodev at this point */
    136 	udp = container_of(video_devdata(filp), struct usbcam_dev, ud_vdev);
    137 
    138 	ufp = (struct usbcam_fh *) kzalloc(sizeof(*ufp), GFP_KERNEL);
    139 	if (!ufp)
    140 		return -ENOMEM;
    141 
    142 	ufp->ufh_dev = udp;
    143 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
    144 	videobuf_queue_init(&ufp->ufh_vbq,
    145 			    &usbcam_videobuf_qops,
    146 			    NULL,
    147 			    NULL,
    148 			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
    149 			    V4L2_FIELD_INTERLACED,
    150 			    sizeof(struct usbcam_frame), ufp);
    151 #else
    152 	videobuf_queue_pci_init(&ufp->ufh_vbq,
    153 			    &usbcam_videobuf_qops,
    154 			    NULL,
    155 			    &slock,
    156 			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
    157 			    V4L2_FIELD_INTERLACED,
    158 			    sizeof(struct usbcam_frame), ufp);
    159 #endif
    160 
    161 	mutex_lock(&udp->ud_open_lock);
    162 
    163 	if (!udp->ud_user_refs) {
    164 		res = usb_autopm_get_interface(udp->ud_intf);
    165 		if (res)
    166 			goto bail_nolock;
    167 		autopm_ref = 1;
    168 	}
    169 
    170 	usbcam_lock(udp);
    171 
    172 	if (udp->ud_disconnected) {
    173 		res = -ENODEV;
    174 		goto bail;
    175 	}
    176 
    177 	if (!udp->ud_user_refs) {
    178 		if (!udp->ud_minidrv->um_ops->no_workref_on_open) {
    179 			res = usbcam_work_ref(udp);
    180 			if (res)
    181 				goto bail;
    182 			work_ref = 1;
    183 		}
    184 
    185 		if (usbcam_minidrv_op_present(udp, open)) {
    186 			res = usbcam_minidrv_op(udp, open);
    187 			if (res) {
    188 				if (work_ref)
    189 					usbcam_work_unref(udp);
    190 				assert(!udp->ud_user_refs);	
    191 				goto bail;
    192 			}
    193 		}
    194 
    195 		/* Transfer the autopm reference */
    196 		assert(autopm_ref);
    197 		autopm_ref = 0;
    198 	}
    199 
    200 	udp->ud_user_refs++;
    201 	filp->private_data = ufp;
    202 	usbcam_get(udp);
    203 
    204 bail:
    205 	usbcam_unlock(udp);
    206 bail_nolock:
    207 	mutex_unlock(&udp->ud_open_lock);
    208 	if (res)
    209 		kfree(ufp);
    210 	if (autopm_ref)
    211 		usb_autopm_put_interface(udp->ud_intf);
    212 	usbcam_work_maybe_stop(udp);
    213 	return res;
    214 }
    215 
    216 static int usbcam_v4l_release(struct inode *inode, struct file *filp)
    217 {
    218 	struct usbcam_fh *ufp = (struct usbcam_fh *) filp->private_data;
    219 	struct usbcam_dev *udp = ufp->ufh_dev;
    220 	int autopm_ref = 0;
    221 
    222 	videobuf_mmap_free(&ufp->ufh_vbq);
    223 
    224 	mutex_lock(&udp->ud_open_lock);
    225 	usbcam_lock(udp);
    226 
    227 	assert(udp->ud_user_refs);
    228 	if (udp->ud_excl_owner == filp)
    229 		udp->ud_excl_owner = NULL;
    230 	kfree(ufp);
    231 	filp->private_data = NULL;
    232 
    233 	if (!--udp->ud_user_refs) {
    234 		usbcam_capture_stop(udp);
    235 
    236 		if (usbcam_minidrv_op_present(udp, close))
    237 			usbcam_minidrv_op(udp, close);
    238 		if (!udp->ud_minidrv->um_ops->no_workref_on_open)
    239 			usbcam_work_unref(udp);
    240 		autopm_ref = 1;
    241 	}
    242 
    243 	usbcam_unlock(udp);
    244 	mutex_unlock(&udp->ud_open_lock);
    245 	if (autopm_ref)
    246 		usb_autopm_put_interface(udp->ud_intf);
    247 	usbcam_work_maybe_stop(udp);
    248 	usbcam_put(udp);
    249 	return 0;
    250 }
    251 
    252 static ssize_t usbcam_v4l_read(struct file *filp, char __user *data,
    253 			       size_t count, loff_t *ppos)
    254 {
    255 	struct usbcam_fh *ufp = (struct usbcam_fh *) filp->private_data;
    256 	ssize_t res;
    257 
    258 	res = videobuf_read_one(&ufp->ufh_vbq, data, count, ppos,
    259 				(filp->f_flags & O_NONBLOCK) ? 1 : 0);
    260 	usbcam_work_maybe_stop(ufp->ufh_dev);
    261 	return res;
    262 }
    263 
    264 static unsigned int usbcam_v4l_poll(struct file *filp,
    265 				    struct poll_table_struct *wait)
    266 {
    267 	struct usbcam_fh *ufp = (struct usbcam_fh *) filp->private_data;
    268 
    269 	return videobuf_poll_stream(filp, &ufp->ufh_vbq, wait);
    270 }
    271 
    272 static int usbcam_v4l_mmap(struct file *filp, struct vm_area_struct * vma)
    273 {
    274 	struct usbcam_fh *ufp = (struct usbcam_fh *) filp->private_data;
    275 
    276 	return videobuf_mmap_mapper(&ufp->ufh_vbq, vma);
    277 }
    278 
    279 static int usbcam_v4l_vidiocgmbuf(struct file *filp, void *fh,
    280 				  struct video_mbuf *p)
    281 {
    282 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    283 	struct usbcam_dev *udp = ufp->ufh_dev;
    284 	struct v4l2_requestbuffers req;
    285 	unsigned int i;
    286 	int res;
    287 
    288 	/*
    289 	 * APPBUG: motion keeps the first mmap, yet requests
    290 	 * larger capture sizes.
    291 	 */
    292 	usbcam_lock(udp);
    293 	ufp->ufh_flags |= USBCAM_FH_USE_FIXED_FB;
    294 	usbcam_unlock(udp);
    295 
    296 	req.type = ufp->ufh_vbq.type;
    297 	req.count = 2;
    298 	req.memory = V4L2_MEMORY_MMAP;
    299 	res = videobuf_reqbufs(&ufp->ufh_vbq, &req);
    300 	if (res == -EBUSY)
    301 	{
    302 		usbcam_dbg(udp, IOCTL_BUF,
    303 			   "VIDIOCGMBUF reqbufs failed: device was busy"
    304 			   " - closing and trying again."); 
    305 		
    306 		res = videobuf_streamoff(&ufp->ufh_vbq);
    307 		if (res < 0)
    308 		{
    309 			usbcam_dbg(udp, IOCTL_BUF,
    310 				   "VIDIOCGMBUF reqbufs failed:"
    311 				   "couldn't free previous buffer.");
    312 			return -EBUSY;
    313 		}
    314 		else
    315 		{
    316 			// we freed previous reqbuf OK.
    317 			usbcam_lock(udp);
    318 			ufp->ufh_flags |= USBCAM_FH_USE_FIXED_FB;
    319 			usbcam_unlock(udp);
    320 
    321 			req.type = ufp->ufh_vbq.type;
    322 			req.count = 2;
    323 			req.memory = V4L2_MEMORY_MMAP;
    324 			res = videobuf_reqbufs(&ufp->ufh_vbq, &req);
    325 		}
    326 	}
    327 	else if (res < 0) {
    328 		usbcam_dbg(udp, IOCTL_BUF,
    329 			   "VIDIOCGMBUF reqbufs failed: %d", res);
    330 		return res;
    331 	}
    332 
    333 	p->frames = req.count;
    334 	p->size = 0;
    335 	for (i = 0; i < p->frames; i++) {
    336 		p->offsets[i] = ufp->ufh_vbq.bufs[i]->boff;
    337 		p->size += ufp->ufh_vbq.bufs[i]->bsize;
    338 	}
    339 
    340 	usbcam_dbg(udp, IOCTL_BUF, "VIDIOCGMBUF frames=%d size=%d",
    341 		   p->frames, p->size);
    342 	return 0;
    343 }
    344 
    345 static void usbcam_dbg_v4l2_buffer_res(struct usbcam_dev *udp, int res,
    346 				       void *arg, const char *prefix)
    347 {
    348 	struct v4l2_buffer *b __attribute__((unused)) =
    349 		(struct v4l2_buffer *) arg;
    350 
    351 	if (res) {
    352 		usbcam_dbg(udp, IOCTL_BUF, "%s res:%d", prefix, res);
    353 		return;
    354 	}
    355 
    356 	usbcam_dbg(udp, IOCTL_BUF, "%s out: index=%d type=%d bytesused=%d "
    357 		   "flags=0x%x field=%d memory=%d m=0x%lx length=%d",
    358 		   prefix, b->index, b->type, b->bytesused,
    359 		   b->flags, b->field, b->memory, b->m.userptr, b->length);
    360 }
    361 
    362 static void usbcam_dbg_v4l2_pix_format(struct usbcam_dev *udp,
    363 				       struct v4l2_pix_format *f,
    364 				       const char *prefix)
    365 {
    366 	__u32 pixfmt = f->pixelformat;
    367 	if (!pixfmt)
    368 		pixfmt = 0x3f3f3f3f;
    369 	usbcam_dbg(udp, IOCTL_FMT, "%s wid=%d hgt=%d fmt=%.4s field=%d "
    370 		   "bpl=%d size=%d cs=%d", prefix,
    371 		   f->width, f->height, (char *) &pixfmt, f->field,
    372 		   f->bytesperline, f->sizeimage, f->colorspace);
    373 }
    374 
    375 static void usbcam_dbg_v4l2_pix_format_res(struct usbcam_dev *udp, int res,
    376 					   struct v4l2_pix_format *f,
    377 					   const char *prefix)
    378 {
    379 	if (res) {
    380 		usbcam_dbg(udp, IOCTL_FMT, "%s %d", prefix, res);
    381 		return;
    382 	}
    383 	usbcam_dbg_v4l2_pix_format(udp, f, prefix);
    384 }
    385 
    386 static int usbcam_v4l_vidioc_reqbufs(struct file *filp, void *fh,
    387 				     struct v4l2_requestbuffers *r)
    388 {
    389 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    390 	struct usbcam_dev *udp = ufp->ufh_dev;
    391 	int res;
    392 
    393 	/* APPBUG: disable USE_FIXED_FB if we enter this path */
    394 	usbcam_lock(udp);
    395 	ufp->ufh_flags &= ~(USBCAM_FH_USE_FIXED_FB);
    396 	usbcam_unlock(udp);
    397 
    398 	usbcam_dbg(udp, IOCTL_BUF,
    399 		   "VIDIOC_REQBUFS count=%d type=%d memory=%d",
    400 		   r->count, r->type, r->memory);
    401 	res = videobuf_reqbufs(&ufp->ufh_vbq, r);
    402 	usbcam_dbg(udp, IOCTL_BUF, "REQBUFS result=%d", res);
    403 	usbcam_work_maybe_stop(udp);
    404 	return res;
    405 }
    406 
    407 static int usbcam_v4l_vidioc_querybuf(struct file *filp, void *fh,
    408 				      struct v4l2_buffer *b)
    409 {
    410 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    411 	struct usbcam_dev *udp = ufp->ufh_dev;
    412 	int res;
    413 
    414 	usbcam_dbg(udp, IOCTL_BUF,
    415 		   "VIDIOC_QUERYBUF in: index=%d type=%d",
    416 		   b->index, b->type);
    417 	res = videobuf_querybuf(&ufp->ufh_vbq, b);
    418 	usbcam_dbg_v4l2_buffer_res(udp, res, b, "VIDIOC_QUERYBUF");
    419 	usbcam_work_maybe_stop(udp);
    420 	return res;
    421 }
    422 
    423 static int usbcam_v4l_vidioc_qbuf(struct file *filp, void *fh,
    424 				  struct v4l2_buffer *b)
    425 {
    426 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    427 	struct usbcam_dev *udp = ufp->ufh_dev;
    428 	int res;
    429 
    430 	/*
    431 	 * APPBUG: ptlib / Ekiga has an issue with zeroing the
    432 	 * flags field before calling QBUF.
    433 	 *
    434 	 * Minidriver support for fast input switching is
    435 	 * unavailable for the time being.
    436 	 */
    437 	b->flags = 0;
    438 
    439 	usbcam_dbg(udp, IOCTL_BUF, "VIDIOC_QBUF in: index=%d type=%d",
    440 		   b->index, b->type);
    441 	res = videobuf_qbuf(&ufp->ufh_vbq, b);
    442 	usbcam_dbg_v4l2_buffer_res(udp, res, b, "VIDIOC_QBUF");
    443 	usbcam_work_maybe_stop(udp);
    444 	return res;
    445 }
    446 
    447 static int usbcam_v4l_vidioc_dqbuf(struct file *filp, void *fh,
    448 				   struct v4l2_buffer *b)
    449 {
    450 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    451 	struct usbcam_dev *udp = ufp->ufh_dev;
    452 	int res;
    453 
    454 	res = videobuf_dqbuf(&ufp->ufh_vbq, b,
    455 			     (filp->f_flags & O_NONBLOCK) ? 1 : 0);
    456 	usbcam_dbg_v4l2_buffer_res(udp, res, b, "VIDIOC_DQBUF");
    457 	usbcam_work_maybe_stop(udp);
    458 	return res;
    459 }
    460 
    461 static int usbcam_v4l_vidioc_streamon(struct file *filp, void *fh,
    462 				      enum v4l2_buf_type f)
    463 {
    464 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    465 	struct usbcam_dev *udp = ufp->ufh_dev;
    466 	int res;
    467 
    468 	if (f != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
    469 		usbcam_dbg(udp, IOCTL_BUF,
    470 			   "VIDIOC_STREAMON: invalid buf type %d", f);
    471 		return -EINVAL;
    472 	}
    473 	if (!udp->ud_excl_owner) {
    474 		usbcam_lock(udp);
    475 		if (!udp->ud_excl_owner)
    476 			udp->ud_excl_owner = filp;
    477 		usbcam_unlock(udp);
    478 	}
    479 	if (udp->ud_excl_owner != filp) {
    480 		usbcam_dbg(udp, IOCTL_BUF,
    481 			   "VIDIOC_STREAMON: not exclusive owner");
    482 		return -EBUSY;
    483 	}
    484 	res = videobuf_streamon(&ufp->ufh_vbq);
    485 	usbcam_dbg(udp, IOCTL_BUF, "VIDIOC_STREAMON: res:%d", res);
    486 	usbcam_work_maybe_stop(udp);
    487 	return res;
    488 }
    489 
    490 static int usbcam_v4l_vidioc_streamoff(struct file *filp, void *fh,
    491 				       enum v4l2_buf_type f)
    492 {
    493 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    494 	struct usbcam_dev *udp = ufp->ufh_dev;
    495 	int res;
    496 
    497 	if (f != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
    498 		usbcam_dbg(udp, IOCTL_BUF,
    499 			   "VIDIOC_STREAMOFF: invalid buf type %d", f);
    500 		return -EINVAL;
    501 	}
    502 	res = videobuf_streamoff(&ufp->ufh_vbq);
    503 	usbcam_dbg(udp, IOCTL_BUF, "VIDIOC_STREAMOFF: res:%d", res);
    504 	usbcam_work_maybe_stop(udp);
    505 	return res;
    506 }
    507 
    508 
    509 /* DEFAULT CAPABILITIES / DEVICE NAME / DRIVER NAME / BUS INFO */
    510 static int usbcam_v4l_vidioc_querycap(struct file *filp, void *fh,
    511 				      struct v4l2_capability *cap)
    512 {
    513 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    514 	struct usbcam_dev *udp = ufp->ufh_dev;
    515 
    516 	usbcam_lock(udp);
    517 	strlcpy(cap->driver,
    518 		usbcam_drvname(udp->ud_minidrv),
    519 		sizeof(cap->driver));
    520 	strlcpy(cap->card, udp->ud_vdev.name, sizeof(cap->card));
    521 	snprintf(cap->bus_info, sizeof(cap->bus_info),
    522 		 "usb:%s", udp->ud_dev->dev.bus_id);
    523 	cap->version = udp->ud_minidrv->um_version;
    524 	cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE |
    525 			     V4L2_CAP_READWRITE |
    526 			     V4L2_CAP_STREAMING);
    527 	usbcam_unlock(udp);
    528 	return 0;
    529 }
    530 
    531 /* DEFAULT FORMAT HANDLING - USE MINDIRIVER CALLOUTS */
    532 static int usbcam_v4l_vidioc_enum_fmt_cap(struct file *filp, void *fh,
    533 					  struct v4l2_fmtdesc *f)
    534 {
    535 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    536 	struct usbcam_dev *udp = ufp->ufh_dev;
    537 	struct usbcam_pix_fmt *pf;
    538 	int res;
    539 
    540 	usbcam_lock(udp);
    541 
    542 	res = -EINVAL;
    543 	if (f->index >= udp->ud_fmt_array_len)
    544 		goto enum_fmt_done;
    545 
    546 	res = 0;
    547 	pf = (struct usbcam_pix_fmt *)
    548 		&(((u8 *) udp->ud_fmt_array)
    549 		  [f->index * udp->ud_fmt_array_elem_size]);
    550 	f->flags = pf->flags;
    551 	f->pixelformat = pf->pixelformat;
    552 	strlcpy(f->description,
    553 		pf->description,
    554 		sizeof(f->description));
    555 
    556 enum_fmt_done:
    557 	usbcam_unlock(udp);
    558 	return res;
    559 }
    560 
    561 static int usbcam_v4l_vidioc_g_fmt_cap(struct file *filp, void *fh,
    562 				       struct v4l2_format *f)
    563 {
    564 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    565 	struct usbcam_dev *udp = ufp->ufh_dev;
    566 
    567 	usbcam_lock(udp);
    568 	f->fmt.pix = udp->ud_format;
    569 	usbcam_unlock(udp);
    570 	usbcam_dbg_v4l2_pix_format(udp, &f->fmt.pix, "VIDIOC_G_FMT: res:");
    571 	return 0;
    572 }
    573 
    574 static int usbcam_v4l_vidioc_s_fmt_cap(struct file *filp, void *fh,
    575 				       struct v4l2_format *f)
    576 {
    577 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    578 	struct usbcam_dev *udp = ufp->ufh_dev;
    579 	int res;
    580 
    581 	usbcam_lock(udp);
    582 
    583 	usbcam_dbg_v4l2_pix_format(udp, &f->fmt.pix,
    584 				   "VIDIOC_S_FMT: param:");
    585 
    586 	if (udp->ud_disconnected) {
    587 		usbcam_dbg(udp, IOCTL_FMT,
    588 			   "VIDIOC_S_FMT: device disconnected");
    589 		res = -EIO;
    590 		goto s_fmt_done;
    591 	}
    592 	if (!udp->ud_excl_owner)
    593 		udp->ud_excl_owner = filp;
    594 	if (!memcmp(&f->fmt.pix, &udp->ud_format, sizeof(f->fmt.pix))) {
    595 		usbcam_dbg(udp, IOCTL_FMT, "VIDIOC_S_FMT: nothing to do");
    596 		res = 0;
    597 		goto s_fmt_done;
    598 	}
    599 	if (!usbcam_minidrv_op_present(udp, set_format)) {
    600 		usbcam_dbg(udp, IOCTL_FMT, "VIDIOC_S_FMT: no minidriver op");
    601 		res = -EINVAL;
    602 		goto s_fmt_done;
    603 	}
    604 	if (udp->ud_excl_owner != filp) {
    605 		usbcam_dbg(udp, IOCTL_FMT,
    606 			   "VIDIOC_S_FMT: not exclusive owner");
    607 		res = -EBUSY;
    608 		goto s_fmt_done;
    609 	}
    610 	usbcam_capture_stop_nondestructive(udp);
    611 	if (udp->ud_capturing) {
    612 		usbcam_dbg(udp, IOCTL_FMT,
    613 			   "VIDIOC_S_FMT: capture in progress");
    614 		res = -EBUSY;
    615 		goto s_fmt_done;
    616 	}
    617 	res = usbcam_minidrv_op(udp, set_format, &f->fmt.pix);
    618 	usbcam_dbg_v4l2_pix_format_res(udp, res, &f->fmt.pix,
    619 				       "VIDIOC_S_FMT: res:");
    620 
    621 s_fmt_done:
    622 	usbcam_unlock(udp);
    623 	return res;
    624 }
    625 
    626 static int usbcam_v4l_vidioc_try_fmt_cap(struct file *filp, void *fh,
    627 					 struct v4l2_format *f)
    628 {
    629 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    630 	struct usbcam_dev *udp = ufp->ufh_dev;
    631 	int res;
    632 
    633 	usbcam_lock(udp);
    634 
    635 	usbcam_dbg_v4l2_pix_format(udp, &f->fmt.pix,
    636 				   "VIDIOC_TRY_FMT: param:");
    637 
    638 	if (udp->ud_disconnected) {
    639 		usbcam_dbg(udp, IOCTL_FMT,
    640 			   "VIDIOC_TRY_FMT: device disconnected");
    641 		res = -EIO;
    642 		goto try_fmt_done;
    643 	}
    644 	if (!usbcam_minidrv_op_present(udp, try_format)) {
    645 		usbcam_dbg(udp, IOCTL_FMT,
    646 			   "VIDIOC_TRY_FMT: no minidriver op");
    647 		res = -EINVAL;
    648 		goto try_fmt_done;
    649 	}
    650 
    651 	res = usbcam_minidrv_op(udp, try_format, &f->fmt.pix);
    652 	usbcam_dbg_v4l2_pix_format_res(udp, res, &f->fmt.pix,
    653 				       "VIDIOC_TRY_FMT: res:");
    654 
    655 try_fmt_done:
    656 	usbcam_unlock(udp);
    657 	usbcam_work_maybe_stop(udp);
    658 	return res;
    659 }
    660 
    661 /* DEFAULT CONTROL HANDLING - USE MINIDRIVER ARRAY / CALLOUTS */
    662 static int usbcam_v4l_vidioc_queryctrl(struct file *filp, void *fh,
    663 				       struct v4l2_queryctrl *a)
    664 {
    665 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    666 	struct usbcam_dev *udp = ufp->ufh_dev;
    667 	const struct usbcam_ctrl *ctrlp, *resp;
    668 	int droplock;
    669 	u32 targ;
    670 	int higher_ids = 0, res = -EINVAL;
    671 
    672 	usbcam_lock(udp);
    673 	droplock = 1;
    674 	targ = a->id;
    675 
    676 	resp = NULL;
    677 
    678 	if (targ & V4L2_CTRL_FLAG_NEXT_CTRL) {
    679 		/*
    680 		 * Find the control with the least ID greater than or
    681 		 * equal to a->id
    682 		 */
    683 		targ &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
    684 		list_for_each_entry(ctrlp, &udp->ud_ctrl_list, uc_links) {
    685 			if (ctrlp->uc_v4l.id <= targ) {
    686 				if (!resp || (ctrlp->uc_v4l.id <
    687 					      resp->uc_v4l.id))
    688 					resp = ctrlp;
    689 			}
    690 		}
    691 
    692 	} else {
    693 		/* Find an exact match */
    694 		list_for_each_entry(ctrlp, &udp->ud_ctrl_list, uc_links) {
    695 			if (ctrlp->uc_v4l.id == targ) {
    696 				resp = ctrlp;
    697 				break;
    698 			}
    699 			else if ((ctrlp->uc_v4l.id >=
    700 				  V4L2_CID_PRIVATE_BASE) &&
    701 				 (ctrlp->uc_v4l.id <
    702 				  (V4L2_CID_PRIVATE_BASE + 1024)) &&
    703 				 (targ >= V4L2_CID_PRIVATE_BASE) &&
    704 				 (targ < ctrlp->uc_v4l.id)) {
    705 				higher_ids = 1;
    706 			}
    707 		}
    708 
    709 		if (!resp && higher_ids) {
    710 			/*
    711 			 * Deal with the private control enumeration
    712 			 * nonsense that the CTRL_FLAG_NEXT_CTRL thing
    713 			 * fixes.
    714 			 */
    715 			memset(a, 0, sizeof(*a));
    716 			a->id = targ;
    717 			a->type = V4L2_CTRL_TYPE_INTEGER;
    718 			strlcpy(a->name, "Disabled", sizeof(a->name));
    719 			a->flags = V4L2_CTRL_FLAG_DISABLED;
    720 			res = 0;
    721 		}
    722 	}
    723 
    724 	if (resp) {
    725 		*a = resp->uc_v4l;
    726 		res = 0;
    727 
    728 		/* Fill in required values for certain types */
    729 		switch (a->type) {
    730 		case V4L2_CTRL_TYPE_BOOLEAN:
    731 			a->minimum = 0;
    732 			a->maximum = 1;
    733 			a->step = 1;
    734 			break;
    735 		case V4L2_CTRL_TYPE_MENU:
    736 			a->step = 1;
    737 			break;
    738 		default:
    739 			break;
    740 		}
    741 
    742 		/*
    743 		 * If a query function was provided, call it to
    744 		 * postprocess the response structure, e.g. to set
    745 		 * flags.
    746 		 */
    747 		if (resp->query_fn) {
    748 			if (udp->ud_minidrv->um_ops->unlocked_ctrl) {
    749 				usbcam_unlock(udp);
    750 				droplock = 0;
    751 			}
    752 			res = resp->query_fn(udp, resp, a);
    753 		}
    754 	}
    755 
    756 	if (droplock)
    757 		usbcam_unlock(udp);
    758 	usbcam_work_maybe_stop(udp);
    759 	return res;
    760 }
    761 
    762 static int usbcam_v4l_vidioc_g_ctrl(struct file *filp, void *fh,
    763 				    struct v4l2_control *a)
    764 {
    765 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    766 	struct usbcam_dev *udp = ufp->ufh_dev;
    767 	const struct usbcam_ctrl *resp;
    768 	struct v4l2_ext_control ec;
    769 	int droplock;
    770 	int res;
    771 
    772 	usbcam_lock(udp);
    773 	droplock = 1;
    774 
    775 	if (udp->ud_disconnected) {
    776 		usbcam_unlock(udp);
    777 		return -EIO;
    778 	}
    779 
    780 	resp = usbcam_ctrl_find(udp, a->id);
    781 	if (!resp ||
    782 	    (resp->uc_v4l.type == V4L2_CTRL_TYPE_BUTTON) ||
    783 	    !resp->get_fn)
    784 		res = -EINVAL;
    785 	else {
    786 		if (udp->ud_minidrv->um_ops->unlocked_ctrl) {
    787 			usbcam_unlock(udp);
    788 			droplock = 0;
    789 		}
    790 		memset(&ec, 0, sizeof(ec));
    791 		ec.id = a->id;
    792 		ec.value = a->value;
    793 		res = resp->get_fn(udp, resp, &ec);
    794 		memset(a, 0, sizeof(*a));
    795 		a->id = ec.id;
    796 		a->value = ec.value;
    797 	}
    798 
    799 	if (droplock)
    800 		usbcam_unlock(udp);
    801 	usbcam_work_maybe_stop(udp);
    802 	return res;
    803 }
    804 
    805 static int usbcam_v4l_vidioc_s_ctrl(struct file *filp, void *fh,
    806 				    struct v4l2_control *a)
    807 {
    808 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    809 	struct usbcam_dev *udp = ufp->ufh_dev;
    810 	const struct usbcam_ctrl *resp;
    811 	struct v4l2_ext_control ec;
    812 	int droplock;
    813 	int res;
    814 
    815 	usbcam_lock(udp);
    816 	droplock = 1;
    817 
    818 	if (udp->ud_disconnected) {
    819 		usbcam_unlock(udp);
    820 		return -EIO;
    821 	}
    822 
    823 	resp = usbcam_ctrl_find(udp, a->id);
    824 	if (!resp) {
    825 		res = -EINVAL;
    826 	} else if (!resp->set_fn) {
    827 		/* Read-only control */
    828 		res = -EBUSY;
    829 	} else if ((resp->uc_v4l.type != V4L2_CTRL_TYPE_BUTTON) &&
    830 		   ((a->value < resp->uc_v4l.minimum) ||
    831 		    (a->value > resp->uc_v4l.maximum))) {
    832 		res = -ERANGE;
    833 	} else {
    834 		if (udp->ud_minidrv->um_ops->unlocked_ctrl) {
    835 			usbcam_unlock(udp);
    836 			droplock = 0;
    837 		}
    838 		memset(&ec, 0, sizeof(ec));
    839 		ec.id = a->id;
    840 		ec.value = a->value;
    841 		res = resp->set_fn(udp, resp, &ec);
    842 		memset(a, 0, sizeof(*a));
    843 		a->id = ec.id;
    844 		a->value = ec.value;
    845 	}
    846 
    847 	if (droplock)
    848 		usbcam_unlock(udp);
    849 	usbcam_work_maybe_stop(udp);
    850 	return res;
    851 }
    852 
    853 static int usbcam_v4l_vidioc_querymenu(struct file *filp, void *fh,
    854 				       struct v4l2_querymenu *a)
    855 {
    856 	struct usbcam_fh *ufp = (struct usbcam_fh *) fh;
    857 	struct usbcam_dev *udp = ufp->ufh_dev;
    858 	const struct usbcam_ctrl *resp;
    859 	int res;
    860 
    861 	usbcam_lock(udp);
    862 
    863 	resp = usbcam_ctrl_find(udp, a->id);
    864 
    865 	if (!resp ||
    866 	    (resp->uc_v4l.type != V4L2_CTRL_TYPE_MENU) ||
    867 	    (a->index > resp->uc_v4l.maximum)) {
    868 		res = -EINVAL;
    869 		goto querymenu_done;
    870 	}
    871 
    872 	strlcpy(a->name,
    873 		resp->uc_menu_names[a->index],
    874 		sizeof(a->name));
    875 	res = 0;
    876 
    877 querymenu_done:
    878 	usbcam_unlock(udp);
    879 	return res;
    880 }
    881 
    882 /* DEFAULT INPUT HANDLING -- There is one input called "Camera" */
    883 static int usbcam_v4l_vidioc_enum_input(struct file *filp, void *fh,
    884 					struct v4l2_input *inp)
    885 {
    886 	const struct v4l2_input dfl_input = {
    887 		.name = "Camera",
    888 		.type = V4L2_INPUT_TYPE_CAMERA,
    889 	};
    890 
    891 	if (inp->index > 0)
    892 		return -EINVAL;
    893 	*inp = dfl_input;
    894 	return 0;
    895 }
    896 
    897 static int usbcam_v4l_vidioc_g_input(struct file *filp, void *fh,
    898 				     unsigned int *i)
    899 {
    900 	*i = 0;
    901 	return 0;
    902 }
    903 
    904 static int usbcam_v4l_vidioc_s_input(struct file *filp, void *fh,
    905 				     unsigned int i)
    906 {
    907 	if (i != 0)
    908 		return -EINVAL;
    909 	return 0;
    910 }
    911 
    912 /* Intercept calls to minidriver V4L handler thing for compat calls. */
    913 static int usbcam_v4l_int_ioctl(struct inode *inodep, struct file *filp,
    914 				unsigned int cmd, void *arg)
    915 {
    916     struct usbcam_fh        *ufp = (struct usbcam_fh *) filp->private_data;
    917 	struct usbcam_dev       *udp = ufp->ufh_dev;
    918 	
    919 	struct v4l2_buffer      buf2;
    920 	enum v4l2_buf_type      captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    921 	int                     err = 0;
    922 	
    923 	
    924 	if (cmd == VIDIOCGCAP) {
    925 	    struct video_capability *cap = (struct video_capability *) arg;
    926 		
    927 		usbcam_lock(udp);
    928 		
    929 		strlcpy(cap->name, udp->ud_vdev.name, sizeof(cap->name));
    930 		cap->type = VID_TYPE_CAPTURE;
    931 		cap->audios = 0;
    932 		cap->channels = 1;	/* only one input source, the camera */
    933 		
    934 		cap->maxwidth = udp->ud_format.width;
    935 		cap->maxheight = udp->ud_format.height;
    936 		
    937 		/*
    938 		 * We lie, here. These values normally return 640x480, which is
    939 		 * actually the maximum, not the minimum. Minimum is usually
    940 		 * 160x120. It's sort of useful to lie since lots of software
    941 		 * just stick with the minimum - we want higher res for the
    942 		 * user where possible.
    943 		*/
    944 		
    945 		cap->minwidth = udp->ud_format.width;
    946 		cap->minheight = udp->ud_format.height;
    947 		
    948 		usbcam_unlock(udp);
    949 		return 0;
    950 	}
    951 	else if (cmd == VIDIOCGCHAN) {
    952 	    struct video_channel *chan = (struct video_channel *) arg;
    953 	    
    954 	    usbcam_lock(udp);
    955 	    
    956 	    chan->channel = 0;
    957 	    strlcpy(chan->name, udp->ud_vdev.name, sizeof(chan->name));
    958 	    chan->tuners = 0;
    959 	    chan->type = VIDEO_TYPE_CAMERA;
    960 	    
    961 	    usbcam_unlock(udp);
    962 	    return 0;
    963 	}
    964 	else if (cmd == VIDIOCSCHAN) {
    965 	    struct video_channel *chan = (struct video_channel *) arg;
    966 	    
    967 	    if (chan->norm != 0)
    968 		    return -EINVAL;
    969 	    return 0;
    970 	}
    971 	else if (cmd == VIDIOCGAUDIO) {
    972 	    return -ENOIOCTLCMD;
    973 	}
    974 	else if (cmd == VIDIOCGTUNER) {
    975 	    return -ENOIOCTLCMD;
    976 	}
    977 	else if (cmd == VIDIOCGPICT) {
    978 	    return -ENOIOCTLCMD;
    979 	}
    980 	else if (cmd == VIDIOCGWIN) {
    981 	    struct video_window *win = (struct video_window *) arg;
    982 	    
    983 	    usbcam_lock(udp);
    984 	    
    985 	    win->x = 0;
    986 	    win->y = 0;
    987 	    win->width = udp->ud_format.width;
    988 	    win->height = udp->ud_format.height;
    989 	    win->chromakey = 0;
    990 	    win->clips = NULL;
    991 	    win->clipcount = 0;
    992 	    win->flags = 0;
    993 	    
    994 	    usbcam_unlock(udp);
    995 	    return 0;
    996 	}
    997 	else if (cmd == VIDIOCGFBUF) {
    998 		struct video_buffer *buf = (struct video_buffer *) arg;
    999 		
   1000 		usbcam_lock(udp);
   1001 		
   1002 		buf->base = NULL;	/* no physical frame buffer access */
   1003 		buf->height = udp->ud_format.height;
   1004 		buf->width = udp->ud_format.width;
   1005 		
   1006 		/*
   1007 		 * graciously stolen from drivers/media/video/v4l1-compat.c
   1008 		 * and modified slightly.
   1009 		 */
   1010 		switch (udp->ud_format.pixelformat) {
   1011 		case V4L2_PIX_FMT_RGB332:
   1012 			buf->depth = 8;
   1013 			break;
   1014 		case V4L2_PIX_FMT_RGB555:
   1015 			buf->depth = 15;
   1016 			break;
   1017 		case V4L2_PIX_FMT_RGB565:
   1018 			buf->depth = 16;
   1019 			break;
   1020 		case V4L2_PIX_FMT_BGR24:
   1021 			buf->depth = 24;
   1022 			break;
   1023 		case V4L2_PIX_FMT_BGR32:
   1024 			buf->depth = 32;
   1025 			break;
   1026 		default:
   1027 			buf->depth = 0;
   1028 		}
   1029 		
   1030 		if (udp->ud_format.bytesperline) {
   1031 			buf->bytesperline = udp->ud_format.bytesperline;
   1032 			
   1033 			/* typically comes out at 16 bit depth as non-rgb */
   1034 			if (!buf->depth && buf->width)
   1035 				buf->depth   = ((udp->ud_format.bytesperline<<3)
   1036 						  + (buf->width-1) )
   1037 						  /buf->width;
   1038 		} else {
   1039 			buf->bytesperline =
   1040 				(buf->width * buf->depth + 7) & 7;
   1041 			buf->bytesperline >>= 3;
   1042 		}
   1043 		
   1044 		usbcam_unlock(udp);
   1045 		return 0;
   1046 	}
   1047 	else if (cmd == VIDIOCGMBUF) {
   1048 	    struct video_mbuf *mbuf = (struct video_mbuf *) arg;
   1049 	    return usbcam_v4l_vidiocgmbuf(filp, filp->private_data, mbuf);
   1050 	}
   1051 	else if (cmd == VIDIOCSFBUF) {
   1052 	    usbcam_warn(udp, "VIDIOCSFBUF called.");
   1053 	    return -ENOIOCTLCMD;
   1054 	}
   1055 	else if (cmd == VIDIOCSWIN) {
   1056 	    return -ENOIOCTLCMD;
   1057 	}
   1058 	else if (cmd == VIDIOCMCAPTURE) {
   1059 	    struct v4l2_format      *fmt2  = NULL;
   1060 	    struct video_mmap	     *mm    = arg;
   1061 
   1062 		fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
   1063 		memset(&buf2,0,sizeof(buf2));
   1064 
   1065 		fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1066 		err = usbcam_v4l_vidioc_g_fmt_cap(filp, filp->private_data, fmt2);
   1067 		if (err < 0) {
   1068 			usbcam_dbg(udp, IOCTL_MISC, "VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n",err);
   1069 			return err;
   1070 		}
   1071 		if (mm->width   != fmt2->fmt.pix.width  ||
   1072 		    mm->height  != fmt2->fmt.pix.height ||
   1073 		    palette_to_pixelformat(mm->format) !=
   1074 		    fmt2->fmt.pix.pixelformat)
   1075 		{/* New capture format...  */
   1076 			fmt2->fmt.pix.width = mm->width;
   1077 			fmt2->fmt.pix.height = mm->height;
   1078 			fmt2->fmt.pix.pixelformat =
   1079 				palette_to_pixelformat(mm->format);
   1080 			fmt2->fmt.pix.field = V4L2_FIELD_ANY;
   1081 			fmt2->fmt.pix.bytesperline = 0;
   1082 			err = usbcam_v4l_vidioc_s_fmt_cap(filp, filp->private_data, fmt2);
   1083 			if (err < 0) {
   1084 				usbcam_dbg(udp, IOCTL_MISC, "VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n",err);
   1085 				return err;
   1086 			}
   1087 		}
   1088 		buf2.index = mm->frame;
   1089 		buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1090 		err = usbcam_v4l_vidioc_querybuf(filp, filp->private_data, &buf2);
   1091 		if (err < 0) {
   1092 			usbcam_dbg(udp, IOCTL_MISC, "VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n",err);
   1093 			return err;
   1094 		}
   1095 		err = usbcam_v4l_vidioc_qbuf(filp, filp->private_data, &buf2);
   1096 		if (err < 0) {
   1097 			usbcam_dbg(udp, IOCTL_MISC, "VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n",err);
   1098 			return err;
   1099 		}
   1100 		err = usbcam_v4l_vidioc_streamon(filp, filp->private_data, captype);
   1101 		if (err < 0)
   1102 			usbcam_dbg(udp, IOCTL_MISC, "VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n",err);
   1103 		return 0;
   1104 	}
   1105 	else if (cmd == VIDIOCSYNC) {
   1106 	    int			*i = arg;
   1107 
   1108 		memset(&buf2,0,sizeof(buf2));
   1109 		buf2.index = *i;
   1110 		buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1111 		err = usbcam_v4l_vidioc_querybuf(filp, filp->private_data, &buf2);
   1112 		if (err < 0) {
   1113 			/*  No such buffer */
   1114 			usbcam_dbg(udp, IOCTL_MISC, "VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
   1115 			return err;
   1116 		}
   1117 		if (!(buf2.flags & V4L2_BUF_FLAG_MAPPED)) {
   1118 			/* Buffer is not mapped  */
   1119 			err = -EINVAL;
   1120 			return err;
   1121 		}
   1122 
   1123 		/* make sure capture actually runs so we don't block forever */
   1124 		err = usbcam_v4l_vidioc_streamon(filp, filp->private_data, captype);
   1125 		if (err < 0) {
   1126 			usbcam_dbg(udp, IOCTL_MISC, "VIDIOCSYNC / VIDIOC_STREAMON: %d\n",err);
   1127 			return err;
   1128 		}
   1129 
   1130 		/*  Loop as long as the buffer is queued, but not done  */
   1131 		while ((buf2.flags &
   1132 			(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
   1133 		       == V4L2_BUF_FLAG_QUEUED)
   1134 		{
   1135 			err = poll_one(filp);
   1136 			if (err < 0 ||	/* error or sleep was interrupted  */
   1137 			    err == 0)	/* timeout? Shouldn't occur.  */
   1138 				return err;
   1139 			err = usbcam_v4l_vidioc_querybuf(filp, filp->private_data, &buf2);
   1140 			if (err < 0)
   1141 				usbcam_dbg(udp, IOCTL_MISC, "VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
   1142 		}
   1143 		if (!(buf2.flags & V4L2_BUF_FLAG_DONE)) /* not done */
   1144 			return err;
   1145 		do {
   1146 		    err = usbcam_v4l_vidioc_dqbuf(filp, filp->private_data, &buf2);
   1147 			if (err < 0)
   1148 				usbcam_dbg(udp, IOCTL_MISC, "VIDIOCSYNC / VIDIOC_DQBUF: %d\n",err);
   1149 		} while (err == 0 && buf2.index != *i);
   1150 		return err;
   1151 	}
   1152 	else {
   1153 	    usbcam_warn(udp, "usbcam_v4l_int_ioctl called without valid ioctl");
   1154 	    return -ENOIOCTLCMD;
   1155 	}
   1156 }
   1157 
   1158 static int usbcam_v4l_ioctl (struct inode *inodep, struct file *file,
   1159 	       unsigned int cmd, unsigned long arg)
   1160 {
   1161     struct usbcam_fh        *ufp = (struct usbcam_fh *) file->private_data;
   1162 	struct usbcam_dev       *udp = ufp->ufh_dev;
   1163 	
   1164 	usbcam_dbg(udp, IOCTL_MISC, "received V4L ioctl: %d\n", cmd);
   1165 	
   1166 #ifdef CONFIG_VIDEO_V4L1_COMPAT
   1167 	if (_IOC_TYPE(cmd) == 'v')
   1168 	{
   1169 		// run our own internal ioctl handler for these V4L compat ioctl.
   1170 		return video_usercopy(inodep, file, cmd, arg, usbcam_v4l_int_ioctl);
   1171 	}
   1172 #endif
   1173 	
   1174 	return video_ioctl2(inodep, file, cmd, arg);
   1175 }
   1176 
   1177 /*
   1178  * The template file_operations structure
   1179  *
   1180  * Each usbcam_minidrv_t contains its own copy of this, which
   1181  * is associated with the video4linux device created for that
   1182  * minidriver.
   1183  *
   1184  * In general, copies will differ only in the .owner field, which
   1185  * will refer to the minidriver module, not usbcam.
   1186  */
   1187 
   1188 struct file_operations usbcam_v4l_fops_template = {
   1189 	.owner		= THIS_MODULE,
   1190 	.open		= usbcam_v4l_open,
   1191 	.release	= usbcam_v4l_release,
   1192 	.read		= usbcam_v4l_read,
   1193 	.poll		= usbcam_v4l_poll,
   1194 	.mmap		= usbcam_v4l_mmap,
   1195 	/*.ioctl		= video_ioctl2,*/
   1196 	.ioctl		= usbcam_v4l_ioctl,
   1197 #ifdef CONFIG_COMPAT
   1198 	.compat_ioctl	= v4l_compat_ioctl32,
   1199 #endif
   1200 	.llseek		= no_llseek,
   1201 };
   1202 
   1203 
   1204 /*
   1205  * The template video_device structure
   1206  *
   1207  * Each usbcam_dev contains its own copy of this.  The minidriver is
   1208  * free to install its own handlers for each interface, although it
   1209  * should take care not to screw up the frame buffer handling.
   1210  *
   1211  * This gets installed via video_register_device() from usb_usbcam_probe().
   1212  */
   1213 
   1214 static const struct v4l2_ioctl_ops this_cam_ops = {
   1215 	.vidioc_querycap	= usbcam_v4l_vidioc_querycap,
   1216 	.vidioc_enum_fmt_vid_cap	= usbcam_v4l_vidioc_enum_fmt_cap,
   1217 	.vidioc_g_fmt_vid_cap	= usbcam_v4l_vidioc_g_fmt_cap,
   1218 	.vidioc_s_fmt_vid_cap	= usbcam_v4l_vidioc_s_fmt_cap,
   1219 	.vidioc_try_fmt_vid_cap	= usbcam_v4l_vidioc_try_fmt_cap,
   1220 	.vidioc_reqbufs		= usbcam_v4l_vidioc_reqbufs,
   1221 	.vidioc_querybuf	= usbcam_v4l_vidioc_querybuf,
   1222 	.vidioc_qbuf		= usbcam_v4l_vidioc_qbuf,
   1223 	.vidioc_dqbuf		= usbcam_v4l_vidioc_dqbuf,
   1224 	.vidiocgmbuf		= usbcam_v4l_vidiocgmbuf,
   1225 	.vidioc_enum_input	= usbcam_v4l_vidioc_enum_input,
   1226 	.vidioc_streamon	= usbcam_v4l_vidioc_streamon,
   1227 	.vidioc_streamoff	= usbcam_v4l_vidioc_streamoff,
   1228 	.vidioc_g_input		= usbcam_v4l_vidioc_g_input,
   1229 	.vidioc_s_input		= usbcam_v4l_vidioc_s_input,
   1230 	.vidioc_queryctrl	= usbcam_v4l_vidioc_queryctrl,
   1231 	.vidioc_g_ctrl		= usbcam_v4l_vidioc_g_ctrl,
   1232 	.vidioc_s_ctrl		= usbcam_v4l_vidioc_s_ctrl,
   1233 	.vidioc_querymenu	= usbcam_v4l_vidioc_querymenu,
   1234 };
   1235 
   1236 struct video_device usbcam_videodev_template = {
   1237 	.name			= "usbcam-unknown",
   1238 	.vfl_type		= VFL_TYPE_GRABBER,
   1239 	.minor			= -1,
   1240 	.ioctl_ops		= &this_cam_ops,
   1241 
   1242 };
   1243