r5u870

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

usbcam_dev.c (27053B)


      1 /*
      2  * USBCAM abstraction library for USB webcam drivers
      3  *
      4  * Copyright (C) 2007 Sam Revitch <samr7 cs washington edu>
      5  *
      6  * This program is free software; you can redistribute it and/or modify
      7  * it under the terms of the GNU General Public License as published by
      8  * the Free Software Foundation; either version 2, or (at your option)
      9  * any later version.
     10  *
     11  * This program is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  * GNU General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU General Public License
     17  * along with this program; if not, write to the Free Software
     18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
     19  */
     20 
     21 #include "usbcam_priv.h"
     22 
     23 /*
     24  * This file contains:
     25  * - Minidriver registration / deregistration handlers.
     26  * - Device and minidriver reference counting functions
     27  * - USB subsystem callouts
     28  */
     29 
     30 /*
     31  * Reference Counting Notes
     32  *
     33  * Each usbcam_minidrv gets:
     34  * - One reference for being in the registered state
     35  * - One reference for each outstanding usbcam_dev
     36  *
     37  * Each usbcam_dev gets:
     38  * - One reference for having its V4L minor registered and not released
     39  * - One reference for having its underlying USB device not disconnected
     40  * - One reference for each open file handle
     41  */
     42 
     43 static void usbcam_minidrv_release(struct kref *kref)
     44 {
     45 	struct usbcam_minidrv *minidrv =
     46 		container_of(kref, struct usbcam_minidrv, um_kref);
     47 
     48 	assert(!minidrv->um_dev_count);
     49 	usbcam_dbgm(minidrv, DEV_STATE, "%s: destroying minidrvier",
     50 		    __FUNCTION__);
     51 	kfree(minidrv);
     52 }
     53 
     54 
     55 static void usbcam_dev_free(struct kref *kref)
     56 {
     57 	struct usbcam_dev *udp =
     58 		container_of(kref, struct usbcam_dev, ud_kref);
     59 
     60 	if (udp->ud_work_refs) {
     61 		usbcam_lock(udp);
     62 		usbcam_warn(udp, "%s: work queue has %d leaked refs",
     63 			    __FUNCTION__, udp->ud_work_refs);
     64 		while (udp->ud_work_refs)
     65 			usbcam_work_unref(udp);
     66 		usbcam_unlock(udp);
     67 	}
     68 
     69 	usbcam_work_maybe_stop(udp);
     70 	assert(!udp->ud_work_thread);
     71 
     72 	usb_put_intf(udp->ud_intf);
     73 	udp->ud_intf = NULL;
     74 
     75 	usb_put_dev(udp->ud_dev);
     76 	udp->ud_dev = NULL;
     77 
     78 	mutex_lock(&udp->ud_minidrv->um_lock);
     79 
     80 	assert(!list_empty(&udp->ud_drv_links));
     81 	assert(udp->ud_minidrv->um_dev_count > 0);
     82 
     83 	list_del_init(&udp->ud_drv_links);
     84 	udp->ud_minidrv->um_dev_count--;
     85 
     86 	mutex_unlock(&udp->ud_minidrv->um_lock);
     87 
     88 	kref_put(&udp->ud_minidrv->um_kref, usbcam_minidrv_release);
     89 	kfree(udp);
     90 }
     91 
     92 static void usbcam_dev_release(struct kref *kref)
     93 {
     94 	struct usbcam_dev *udp =
     95 		container_of(kref, struct usbcam_dev, ud_kref);
     96 
     97 	usbcam_dbg(udp, DEV_STATE, "%s: destroying device", __FUNCTION__);
     98 
     99 	if (usbcam_minidrv_op_present(udp, release)) {
    100 		usbcam_lock(udp);
    101 		usbcam_ctrl_releaseall(udp);
    102 		usbcam_minidrv_op(udp, release);
    103 		usbcam_unlock(udp);
    104 	}
    105 	usbcam_dev_free(kref);
    106 }
    107 
    108 void usbcam_put(struct usbcam_dev *udp)
    109 {
    110 	kref_put(&udp->ud_kref, usbcam_dev_release);
    111 }
    112 USBCAM_EXPORT_SYMBOL(usbcam_put);
    113 
    114 /*
    115  * V4L2 videodev callout implementations
    116  */
    117 
    118 static void usbcam_videodev_release(struct video_device *vfd)
    119 {
    120 	struct usbcam_dev *udp = container_of(vfd, struct usbcam_dev, ud_vdev);
    121 
    122 	usbcam_lock(udp);
    123 
    124 	assert(!udp->ud_videodev_released);
    125 	udp->ud_videodev_released = 1;
    126 
    127 	usbcam_unlock(udp);
    128 	usbcam_put(udp);
    129 }
    130 
    131 
    132 /*
    133  * USB subsystem operation implementations
    134  */
    135 
    136 struct usbcam_claimed_interface {
    137 	struct list_head	ui_links;
    138 	struct usb_interface	*ui_intf;
    139 };
    140 
    141 static int usbcam_usb_probe(struct usb_interface *intf,
    142 			    const struct usb_device_id *devid)
    143 {
    144 	struct usb_driver *drvp;
    145 	struct usbcam_dev *udp = NULL, *udpx;
    146 	usbcam_minidrv_t *minidrv;
    147 	struct usb_device *dev;
    148 	struct list_head *listp;
    149 	struct usbcam_claimed_interface *cip;
    150 	int minidrv_init_failed = 0;
    151 	int res, i;
    152 
    153 	/* Locate the mini-driver */
    154 	dev = interface_to_usbdev(intf);
    155 	drvp = to_usb_driver(intf->dev.driver);
    156 	minidrv = container_of(drvp, usbcam_minidrv_t, um_usbdrv);
    157 
    158 	/* Allocate and initialize a device structure */
    159 	udp = (struct usbcam_dev *) kzalloc(sizeof(*udp) +
    160 					    minidrv->um_dev_privsize,
    161 					    GFP_KERNEL);
    162 	if (!udp)
    163 		return -ENOMEM;
    164 
    165 	INIT_LIST_HEAD(&udp->ud_ctrl_list);
    166 	mutex_init(&udp->ud_open_lock);
    167 	mutex_init(&udp->ud_lock);
    168 	spin_lock_init(&udp->ud_work_lock);
    169 	INIT_LIST_HEAD(&udp->ud_work_queue);
    170 	udp->ud_minidrv = minidrv;
    171 	udp->ud_dev = usb_get_dev(dev);
    172 	udp->ud_intf = usb_get_intf(intf);
    173 	udp->ud_debug = minidrv->um_debug;
    174 	INIT_LIST_HEAD(&udp->ud_drv_links);
    175 	kref_init(&udp->ud_kref);
    176 
    177 	INIT_LIST_HEAD(&udp->ud_interface_list);
    178 	INIT_LIST_HEAD(&udp->ud_frame_cap_queue);
    179 
    180 	if (minidrv->um_dev_privsize)
    181 		udp->ud_minidrv_data = &udp[1];
    182 
    183 	/* Set up the video4linux structure */
    184 	udp->ud_vdev = minidrv->um_videodev_template;
    185 	udp->ud_vdev.release = usbcam_videodev_release;
    186 
    187 	/* Add the device to the minidriver's list of active devices */
    188 	usbcam_lock(udp);
    189 
    190 	mutex_lock(&minidrv->um_lock);
    191 
    192 	/* Inefficiently find an unused ID in the device list */
    193 	i = 0;
    194 	udpx = NULL;
    195 	list_for_each(listp, &minidrv->um_dev_list) {
    196 		udpx = list_entry(listp, struct usbcam_dev, ud_drv_links);
    197 		if (udpx->ud_minidrv_id < 0) {
    198 			udpx = NULL;
    199 			continue;
    200 		}
    201 		if (udpx->ud_minidrv_id != i)
    202 			break;
    203 		udpx = NULL;
    204 		i++;
    205 	}
    206 
    207 	udp->ud_minidrv_id = i;
    208 	if (udpx) {
    209 		list_add_tail(&udp->ud_drv_links, &udpx->ud_drv_links);
    210 	} else {
    211 		list_add_tail(&udp->ud_drv_links, &minidrv->um_dev_list);
    212 	}
    213 
    214 	minidrv->um_dev_count++;
    215 	kref_get(&minidrv->um_kref);
    216 
    217 	snprintf(udp->ud_dev_name, sizeof(udp->ud_dev_name),
    218 		 "%s-%d", usbcam_drvname(udp->ud_minidrv),
    219 		 udp->ud_minidrv_id);
    220 
    221 	snprintf(udp->ud_vdev.name, sizeof(udp->ud_vdev.name),
    222 		 "%s USB Camera #%d",
    223 		 usbcam_drvname(minidrv), udp->ud_minidrv_id + 1);
    224 
    225 
    226 	mutex_unlock(&minidrv->um_lock);
    227 
    228 	/* Invoke the minidriver initialization callout */
    229 	udp->ud_initializing = 1;
    230 	res = usbcam_minidrv_op(udp, init, devid);
    231 	udp->ud_initializing = 0;
    232 	if (res) {
    233 		usbcam_dbg(udp, DEV_STATE, "minidriver init failed: %d", res);
    234 		minidrv_init_failed = 1;
    235 		goto out_nodisconn;
    236 	}
    237 
    238 	/* Complain if the device isn't filled out correctly */
    239 	if (!udp->ud_format.width || !udp->ud_format.height) {
    240 		usbcam_warn(udp, "minidriver did not set default size");
    241 		res = -EINVAL;
    242 		goto out;
    243 	}
    244 	if (!udp->ud_format.pixelformat) {
    245 		usbcam_warn(udp, "minidriver did not set default pixelformat");
    246 		res = -EINVAL;
    247 		goto out;
    248 	}
    249 
    250 	usb_set_intfdata(intf, udp);
    251 	usbcam_unlock(udp);
    252 
    253 	/*
    254 	 * Register the device with video4linux
    255 	 *
    256 	 * BUG: video_register_device() may or may not call back
    257 	 * into usbcam_videodev_release(), depending on how it fails,
    258 	 * and if it does call back, its callback may be latent.
    259 	 *
    260 	 * We will assume no callback on failure.
    261 	 */
    262 
    263 	if (udp->ud_vdev.minor != -1) {
    264 		/* Minidriver has indicated its preference for a minor */
    265 		res = video_register_device(&udp->ud_vdev, VFL_TYPE_GRABBER,
    266 					    -1);
    267 		if (!res)
    268 			goto video_registered;
    269 	}
    270 
    271 	for (i = 0; i < minidrv->um_video_nr_array_len; i++) {
    272 		res = video_register_device(&udp->ud_vdev, VFL_TYPE_GRABBER,
    273 					    minidrv->um_video_nr_array[i]);
    274 		if (!res)
    275 			goto video_registered;
    276 	}
    277 
    278 	res = video_register_device(&udp->ud_vdev, VFL_TYPE_GRABBER, -1);
    279 	if (res) {
    280 		usbcam_err(udp, "%s: video_register_device failed",
    281 			   __FUNCTION__);
    282 		usbcam_lock(udp);
    283 		assert(!udp->ud_videodev_released);
    284 		udp->ud_videodev_released = 1;
    285 		goto out;
    286 	}
    287 
    288 video_registered:
    289 	usbcam_get(udp);
    290 	/*
    291 	 * There should now be at least two references on udp:
    292 	 * One for the primary USB interface in the non-disconnected state
    293 	 * One for the videodev stuff
    294 	 * One for each additional claimed interface
    295 	 */
    296 
    297 	usbcam_info(udp, "registered as video%d", udp->ud_vdev.minor);
    298 
    299 	usbcam_work_maybe_stop(udp);
    300 	return 0;
    301 
    302 out:
    303 	assert(!udp->ud_disconnected);
    304 	udp->ud_disconnected = 1;
    305 	if (usbcam_minidrv_op_present(udp, disconnect))
    306 		usbcam_minidrv_op(udp, disconnect);
    307 
    308 out_nodisconn:
    309 	while (!list_empty(&udp->ud_interface_list)) {
    310 		cip = list_entry(udp->ud_interface_list.next,
    311 				 struct usbcam_claimed_interface,
    312 				 ui_links);
    313 		list_del_init(&cip->ui_links);
    314 		usb_set_intfdata(cip->ui_intf, NULL);
    315 		usb_driver_release_interface(&minidrv->um_usbdrv,
    316 					     cip->ui_intf);
    317 		usb_put_intf(cip->ui_intf);
    318 		kfree(cip);
    319 		usbcam_put(udp);
    320 	}
    321 
    322 	usbcam_unlock(udp);
    323 
    324 	if (minidrv_init_failed)
    325 		kref_put(&udp->ud_kref, usbcam_dev_free);
    326 	else
    327 		usbcam_put(udp);
    328 	return res;
    329 }
    330 
    331 static void usbcam_usb_disconnect(struct usb_interface *intf)
    332 {
    333 	struct usbcam_dev *udp = (struct usbcam_dev *) usb_get_intfdata(intf);
    334 	struct usbcam_claimed_interface *iterp, *cip;
    335 	int put_intf = 0;
    336 	int put_udp = 0;
    337 
    338 	if (!udp)
    339 		return;
    340 
    341 	usbcam_lock(udp);
    342 	if (!udp->ud_disconnected) {
    343 		udp->ud_disconnected = 1;
    344 		usbcam_unlock(udp);
    345 
    346 		usbcam_dbg(udp, DEV_STATE, "disconnected");
    347 		video_unregister_device(&udp->ud_vdev);
    348 
    349 		usbcam_dbg(udp, DEV_STATE, "unregistered from video%d",
    350 			   udp->ud_vdev.minor);
    351 
    352 		usbcam_lock(udp);
    353 		if (usbcam_minidrv_op_present(udp, disconnect))
    354 			usbcam_minidrv_op(udp, disconnect);
    355 
    356 		usbcam_capture_stop(udp);
    357 	}
    358 
    359 	if (intf == udp->ud_intf) {
    360 		assert(!udp->ud_disconnected_primary);
    361 		udp->ud_disconnected_primary = 1;
    362 		put_udp = 1;
    363 
    364 	} else {
    365 		cip = NULL;
    366 		list_for_each_entry(iterp, &udp->ud_interface_list, ui_links) {
    367 			if (iterp->ui_intf == intf) {
    368 				cip = iterp;
    369 				break;
    370 			}
    371 		}
    372 
    373 		if (cip) {
    374 			list_del_init(&cip->ui_links);
    375 			kfree(cip);
    376 			put_intf = 1;
    377 			put_udp = 1;
    378 		} else {
    379 			usbcam_err(udp, "interface %p is not claimed", intf);
    380 		}
    381 	}
    382 
    383 	usb_set_intfdata(intf, NULL);
    384 	usbcam_unlock(udp);
    385 
    386 	usbcam_work_maybe_stop(udp);
    387 
    388 	if (put_intf)
    389 		usb_put_intf(intf);
    390 	if (put_udp)
    391 		usbcam_put(udp);
    392 }
    393 
    394 #if defined(CONFIG_PM)
    395 static int usbcam_usb_suspend(struct usb_interface *intf, pm_message_t msg)
    396 {
    397 	struct usbcam_dev *udp = (struct usbcam_dev *) usb_get_intfdata(intf);
    398 	int relock = 0, res = 0;
    399 	if (!udp) {
    400 		printk(KERN_WARNING "%s: no associated device\n",
    401 		       __FUNCTION__);
    402 		return 0;
    403 	}
    404 
    405 	usbcam_lock(udp);
    406 	if ((intf != udp->ud_intf) || udp->ud_suspended) {
    407 		/* Do nothing */
    408 	} else if (usbcam_minidrv_op_present(udp, suspend)) {
    409 		usbcam_dbg(udp, DEV_STATE, "invoking minidriver suspend");
    410 		udp->ud_suspended = 1;
    411 		if (udp->ud_minidrv->um_ops->unlocked_pm) {
    412 			usbcam_unlock(udp);
    413 			relock = 1;
    414 		}
    415 
    416 		res = usbcam_minidrv_op(udp, suspend, msg);
    417 
    418 		if (relock)
    419 			usbcam_lock(udp);
    420 		if (res)
    421 			udp->ud_suspended = 0;
    422 	} else {
    423 		usbcam_dbg(udp, DEV_STATE, "no minidriver suspend method");
    424 		udp->ud_suspended = 1;
    425 	}
    426 
    427 	usbcam_unlock(udp);
    428 	usbcam_work_maybe_stop(udp);
    429 	return res;
    430 }
    431 
    432 static int usbcam_usb_resume(struct usb_interface *intf)
    433 {
    434 	struct usbcam_dev *udp = (struct usbcam_dev *) usb_get_intfdata(intf);
    435 	int relock = 0, res = 0;
    436 	if (!udp) {
    437 		printk(KERN_WARNING "%s: no associated device\n",
    438 		       __FUNCTION__);
    439 		return 0;
    440 	}
    441 
    442 	usbcam_lock(udp);
    443 	if ((intf != udp->ud_intf) || !udp->ud_suspended) {
    444 		/* Nothing to do! */
    445 	} else if (usbcam_minidrv_op_present(udp, resume)) {
    446 		usbcam_dbg(udp, DEV_STATE, "invoking minidriver resume");
    447 		if (udp->ud_minidrv->um_ops->unlocked_pm) {
    448 			usbcam_unlock(udp);
    449 			relock = 1;
    450 		}
    451 		res = usbcam_minidrv_op(udp, resume);
    452 		if (relock)
    453 			usbcam_lock(udp);
    454 	} else
    455 		usbcam_dbg(udp, DEV_STATE, "no minidriver resume method");
    456 
    457 	if (!res)
    458 		udp->ud_suspended = 0;
    459 
    460 	usbcam_unlock(udp);
    461 	usbcam_work_maybe_stop(udp);
    462 	return res;
    463 }
    464 #endif  /* defined(CONFIG_PM) */
    465 
    466 
    467 static const struct usb_driver usbcam_usb_driver_template = {
    468 	.name		= "usbcam minidriver",
    469 	.probe		= usbcam_usb_probe,
    470 	.disconnect	= usbcam_usb_disconnect,
    471 #if defined(CONFIG_PM)
    472 	.suspend	= usbcam_usb_suspend,
    473 	.resume		= usbcam_usb_resume,
    474 #endif
    475 };
    476 
    477 
    478 /*
    479  * Minidriver registration/unregistration
    480  */
    481 
    482 int usbcam_register_mod(usbcam_minidrv_t **driverpp,
    483 			int minidrv_version, const char *minidrv_verx,
    484 			const struct usbcam_dev_ops *ops,
    485 			const int dev_priv_size,
    486 			const struct usb_device_id *id_table,
    487 			const int *video_nrs, int video_nrs_len,
    488 			int *debug, struct module *md, const char *modname)
    489 {
    490 	usbcam_minidrv_t *minidrv;
    491 	int res;
    492 
    493 	printk(KERN_INFO "usbcam: registering driver %s %d.%d.%d%s\n",
    494 	       modname,
    495 	       (minidrv_version >> 16) & 0xff,
    496 	       (minidrv_version >> 8) & 0xff,
    497 	       minidrv_version & 0xff,
    498 	       minidrv_verx ? minidrv_verx : "");
    499 
    500 	minidrv = (usbcam_minidrv_t *) kzalloc(sizeof(*minidrv), GFP_KERNEL);
    501 	if (!minidrv) {
    502 		err("%s: Failed to allocate usbcam_minidrv_t", __FUNCTION__);
    503 		return -ENOMEM;
    504 	}
    505 
    506 	kref_init(&minidrv->um_kref);
    507 	minidrv->um_owner = md;
    508 	minidrv->um_modname = modname;
    509 	minidrv->um_version = minidrv_version;
    510 	minidrv->um_debug = debug;
    511 	minidrv->um_dev_privsize = dev_priv_size;
    512 	INIT_LIST_HEAD(&minidrv->um_dev_list);
    513 	mutex_init(&minidrv->um_lock);
    514 	minidrv->um_video_nr_array = video_nrs;
    515 	minidrv->um_video_nr_array_len = video_nrs_len;
    516 
    517 	minidrv->um_ops = ops;
    518 
    519 	minidrv->um_usbdrv = usbcam_usb_driver_template;
    520 	minidrv->um_usbdrv.name = usbcam_drvname(minidrv);
    521 	minidrv->um_usbdrv.id_table = id_table;
    522 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
    523 	minidrv->um_usbdrv.supports_autosuspend =
    524 		minidrv->um_ops->supports_autosuspend;
    525 #endif
    526 
    527 	/*
    528 	 * We have a separate fops per minidriver structure so that
    529 	 * module reference counting works without egregious hacks.
    530 	 */
    531 	minidrv->um_v4l_fops = usbcam_v4l_fops_template;
    532 	minidrv->um_v4l_fops.owner = minidrv->um_owner;
    533 
    534 	minidrv->um_videodev_template = usbcam_videodev_template;
    535 	minidrv->um_videodev_template.fops = &minidrv->um_v4l_fops;
    536 
    537 	*driverpp = minidrv;
    538 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
    539 	res = usb_register_driver(&minidrv->um_usbdrv, minidrv->um_owner,
    540 				  minidrv->um_modname);
    541 #else
    542 	res = usb_register_driver(&minidrv->um_usbdrv, minidrv->um_owner);
    543 #endif
    544 	if (res) {
    545 		kref_put(&minidrv->um_kref, usbcam_minidrv_release);
    546 		*driverpp = NULL;
    547 	}
    548 
    549 	usbcam_dbgm(minidrv, DEV_STATE, "registered minidriver");
    550 
    551 	return res;
    552 }
    553 USBCAM_EXPORT_SYMBOL(usbcam_register_mod);
    554 
    555 void usbcam_unregister(usbcam_minidrv_t *minidrv)
    556 {
    557 	usbcam_dbgm(minidrv, DEV_STATE, "unregistering minidriver");
    558 
    559 	usb_deregister(&minidrv->um_usbdrv);
    560 
    561 	if (minidrv->um_dev_count) {
    562 		/*
    563 		 * This can happen if minidrivers unregister prior to
    564 		 * module_exit(), but is usually bad.
    565 		 */
    566 		err("%s: %d \"%s\" devices remain",
    567 		    __FUNCTION__, minidrv->um_dev_count,
    568 		    usbcam_drvname(minidrv));
    569 	}
    570 
    571 	kref_put(&minidrv->um_kref, usbcam_minidrv_release);
    572 }
    573 USBCAM_EXPORT_SYMBOL(usbcam_unregister);
    574 
    575 
    576 int usbcam_claim_interface(struct usbcam_dev *udp, int ifnum)
    577 {
    578 	struct usb_interface *intf;
    579 	struct usbcam_claimed_interface *cip;
    580 	int res;
    581 
    582 	usbcam_chklock(udp);
    583 
    584 	if (!udp->ud_initializing) {
    585 		usbcam_warn(udp, "%s may only be called from minidriver init",
    586 			    __FUNCTION__);
    587 		return -EINVAL;
    588 	}
    589 
    590 	intf = usb_ifnum_to_if(udp->ud_dev, ifnum);
    591 	if (!intf) {
    592 		usbcam_warn(udp, "%s: interface %d does not exist",
    593 			    __FUNCTION__, ifnum);
    594 		return -ENODEV;
    595 	}
    596 
    597 	res = usb_driver_claim_interface(&udp->ud_minidrv->um_usbdrv,
    598 					 intf, NULL);
    599 
    600 	if (!res) {
    601 		cip = kmalloc(sizeof(*cip), GFP_KERNEL);
    602 		if (!cip) {
    603 			usb_driver_release_interface(&udp->ud_minidrv->
    604 						     um_usbdrv, intf);
    605 			return -ENOMEM;
    606 		}
    607 
    608 		INIT_LIST_HEAD(&cip->ui_links);
    609 		cip->ui_intf = usb_get_intf(intf);
    610 		usb_set_intfdata(intf, udp);
    611 		usbcam_get(udp);
    612 		list_add_tail(&cip->ui_links, &udp->ud_interface_list);
    613 	}
    614 
    615 	return res;
    616 }
    617 USBCAM_EXPORT_SYMBOL(usbcam_claim_interface);
    618 
    619 
    620 /*
    621  * Work queue implementation
    622  */
    623 
    624 static DECLARE_WAIT_QUEUE_HEAD(usbcam_work_idle_wait);
    625 
    626 static int usbcam_work_thread(void *arg)
    627 {
    628 	struct usbcam_dev *udp = (struct usbcam_dev *) arg;
    629 	struct usbcam_workitem *wip;
    630 	sigset_t wakesigs;
    631 	unsigned long flags;
    632 	usbcam_workfunc_t fn;
    633 	int res;
    634 
    635 	current->flags |= PF_NOFREEZE;
    636 	set_user_nice(current, -5);
    637 
    638 	sigemptyset(&wakesigs);
    639 	sigaddset(&wakesigs, SIGUSR1);
    640 
    641 	while (1) {
    642 		/* Wait for something to appear on the work queue */
    643 		spin_lock_irqsave(&udp->ud_work_lock, flags);
    644 		udp->ud_work_lockwait = 0;
    645 		if (list_empty(&udp->ud_work_queue)) {
    646 			if (kthread_should_stop()) {
    647 				spin_unlock_irqrestore(&udp->ud_work_lock,
    648 						       flags);
    649 				break;
    650 			}
    651 
    652 			set_current_state(TASK_INTERRUPTIBLE);
    653 			wake_up_all(&usbcam_work_idle_wait);
    654 			spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    655 			schedule();
    656 			spin_lock_irqsave(&udp->ud_work_lock, flags);
    657 		}
    658 		udp->ud_work_lockwait = 1;
    659 		spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    660 
    661 		/* Enable the mutex wait cancelation signal */
    662 		sigprocmask(SIG_UNBLOCK, &wakesigs, NULL);
    663 
    664 		/* Re-check the queue, wait if it's still nonempty */
    665 		res = -EINTR;
    666 		if (!list_empty(&udp->ud_work_queue))
    667 			res = mutex_lock_interruptible(&udp->ud_lock);
    668 
    669 		/* Disable the mutex wait cancelation signal */
    670 		sigprocmask(SIG_BLOCK, &wakesigs, NULL);
    671 		flush_signals(current);
    672 
    673 		if (res)
    674 			continue;
    675 
    676 		wip = NULL;
    677 		spin_lock_irqsave(&udp->ud_work_lock, flags);
    678 		udp->ud_work_lockwait = 0;
    679 		if (!list_empty(&udp->ud_work_queue)) {
    680 			wip = container_of(udp->ud_work_queue.next,
    681 					   struct usbcam_workitem,
    682 					   uw_links);
    683 			list_del_init(&wip->uw_links);
    684 		}
    685 
    686 		spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    687 
    688 		if (wip) {
    689 			fn = wip->uw_func;
    690 			fn(wip);
    691 		}
    692 
    693 		usbcam_unlock(udp);
    694 	}
    695 
    696 	return 0;
    697 }
    698 
    699 void usbcam_work_init(struct usbcam_dev *udp, struct usbcam_workitem *wip,
    700 		      usbcam_workfunc_t func)
    701 {
    702 	INIT_LIST_HEAD(&wip->uw_links);
    703 	wip->uw_dev = udp;
    704 	wip->uw_func = func;
    705 }
    706 USBCAM_EXPORT_SYMBOL(usbcam_work_init);
    707 
    708 int usbcam_work_queue(struct usbcam_workitem *wip)
    709 {
    710 	struct usbcam_dev *udp = wip->uw_dev;
    711 	unsigned long flags;
    712 	int res;
    713 
    714 	assert(udp != NULL);
    715 
    716 	spin_lock_irqsave(&udp->ud_work_lock, flags);
    717 	if (!list_empty(&wip->uw_links)) {
    718 		res = -EALREADY;
    719 		assert(wip->uw_dev == udp);
    720 	} else if (udp->ud_work_refs) {
    721 		res = 0;
    722 		wip->uw_dev = udp;
    723 		list_add_tail(&wip->uw_links, &udp->ud_work_queue);
    724 		if (udp->ud_work_queue.next == &wip->uw_links)
    725 			wake_up_process(udp->ud_work_thread);
    726 	} else {
    727 		res = -EBUSY;
    728 	}
    729 	spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    730 
    731 	return res;
    732 }
    733 USBCAM_EXPORT_SYMBOL(usbcam_work_queue);
    734 
    735 int usbcam_work_cancel(struct usbcam_workitem *wip)
    736 {
    737 	struct usbcam_dev *udp = wip->uw_dev;
    738 	unsigned long flags;
    739 	int res, wakeit = 0;
    740 
    741 	assert(udp != NULL);
    742 	usbcam_chklock(udp);
    743 
    744 	res = -ENOENT;
    745 	spin_lock_irqsave(&udp->ud_work_lock, flags);
    746 	if (!list_empty(&wip->uw_links)) {
    747 		res = 0;
    748 		assert(wip->uw_dev == udp);
    749 		if ((udp->ud_work_queue.next == &wip->uw_links) &&
    750 		    udp->ud_work_lockwait)
    751 			wakeit = 1;
    752 		list_del_init(&wip->uw_links);
    753 		if (wakeit)
    754 			force_sig(SIGUSR1, udp->ud_work_thread);
    755 	}
    756 	spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    757 
    758 	return res;
    759 }
    760 USBCAM_EXPORT_SYMBOL(usbcam_work_cancel);
    761 
    762 int usbcam_work_ref(struct usbcam_dev *udp)
    763 {
    764 	struct task_struct *kt_new;
    765 	unsigned long flags;
    766 
    767 	usbcam_chklock(udp);
    768 
    769 	/*
    770 	 * We adjust this value under the spinlock to synchronize with
    771 	 * usbcam_work_queue().
    772 	 */
    773 	spin_lock_irqsave(&udp->ud_work_lock, flags);
    774 	udp->ud_work_refs++;
    775 	spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    776 
    777 	if (!udp->ud_work_thread) {
    778 		kt_new = kthread_create(usbcam_work_thread, udp,
    779 					udp->ud_dev_name);
    780 		if (!kt_new) {
    781 			usbcam_err(udp, "%s: could not create worker thread",
    782 				   __FUNCTION__);
    783 			return -ENOMEM;
    784 		}
    785 
    786 		spin_lock_irqsave(&udp->ud_work_lock, flags);
    787 		udp->ud_work_thread = kt_new;
    788 		spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    789 	}
    790 
    791 	return 0;
    792 }
    793 USBCAM_EXPORT_SYMBOL(usbcam_work_ref);
    794 
    795 void usbcam_work_unref(struct usbcam_dev *udp)
    796 {
    797 	unsigned long flags;
    798 
    799 	usbcam_chklock(udp);
    800 
    801 	if (!udp->ud_work_refs) {
    802 		usbcam_warn(udp, "%s: work queue has zero refs", __FUNCTION__);
    803 		return;
    804 	}
    805 
    806 	spin_lock_irqsave(&udp->ud_work_lock, flags);
    807 	udp->ud_work_refs--;
    808 	spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    809 }
    810 USBCAM_EXPORT_SYMBOL(usbcam_work_unref);
    811 
    812 void usbcam_work_runqueue(struct usbcam_dev *udp)
    813 {
    814 	struct usbcam_workitem *wip;
    815 	unsigned long flags;
    816 	usbcam_workfunc_t fn;
    817 
    818 	usbcam_chklock(udp);
    819 
    820 	spin_lock_irqsave(&udp->ud_work_lock, flags);
    821 	while (!list_empty(&udp->ud_work_queue)) {
    822 		wip = container_of(udp->ud_work_queue.next,
    823 				   struct usbcam_workitem,
    824 				   uw_links);
    825 		list_del_init(&wip->uw_links);
    826 		spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    827 
    828 		fn = wip->uw_func;
    829 		fn(wip);
    830 
    831 		spin_lock_irqsave(&udp->ud_work_lock, flags);
    832 	}
    833 	spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    834 }
    835 USBCAM_EXPORT_SYMBOL(usbcam_work_runqueue);
    836 
    837 
    838 void usbcam_work_stop(struct usbcam_dev *udp)
    839 {
    840 	struct task_struct *kt_stop = NULL;
    841 	unsigned long flags;
    842 
    843 	usbcam_lock(udp);
    844 
    845 	if (!udp->ud_work_refs) {
    846 		/* Prevent further tasks from being queued */
    847 		spin_lock_irqsave(&udp->ud_work_lock, flags);
    848 		kt_stop = udp->ud_work_thread;
    849 		udp->ud_work_thread = NULL;
    850 		spin_unlock_irqrestore(&udp->ud_work_lock, flags);
    851 	}
    852 
    853 	usbcam_unlock(udp);
    854 
    855 	if (kt_stop) {
    856 		/*
    857 		 * Wait for the queue to empty out, then stop the
    858 		 * thread.  It might be easier to just call
    859 		 * usbcam_work_flush() and execute the remaining
    860 		 * tasks synchronously in the current thread.
    861 		 */
    862 		wait_event(usbcam_work_idle_wait,
    863 			   list_empty(&udp->ud_work_queue));
    864 		kthread_stop(kt_stop);
    865 	}
    866 }
    867 
    868 
    869 static void usbcam_delayedwork_timeout(unsigned long data)
    870 {
    871 	struct usbcam_delayedwork *dwp = (struct usbcam_delayedwork *) data;
    872 	int res;
    873 	res = usbcam_work_queue(&dwp->dw_work);
    874 	if (res)
    875 		usbcam_warn(dwp->dw_work.uw_dev,
    876 			    "delayed work item submit failed: %d", res);
    877 }
    878 
    879 void usbcam_delayedwork_init(struct usbcam_dev *udp,
    880 			     struct usbcam_delayedwork *dwp,
    881 			     usbcam_workfunc_t func)
    882 {
    883 	usbcam_work_init(udp, &dwp->dw_work, func);
    884 	setup_timer(&dwp->dw_timer,
    885 		    usbcam_delayedwork_timeout,
    886 		    (unsigned long) dwp);
    887 }
    888 USBCAM_EXPORT_SYMBOL(usbcam_delayedwork_init);
    889 
    890 void usbcam_delayedwork_queue(struct usbcam_delayedwork *dwp,
    891 			      unsigned int timeout_ms)
    892 {
    893 	dwp->dw_timer.expires = jiffies + ((timeout_ms * HZ) / 1000);
    894 	add_timer(&dwp->dw_timer);
    895 }	
    896 USBCAM_EXPORT_SYMBOL(usbcam_delayedwork_queue);
    897 
    898 int usbcam_delayedwork_cancel(struct usbcam_delayedwork *dwp)
    899 {
    900 	if (timer_pending(&dwp->dw_timer) && del_timer_sync(&dwp->dw_timer))
    901 		return 0;
    902 	return usbcam_work_cancel(&dwp->dw_work);
    903 }
    904 USBCAM_EXPORT_SYMBOL(usbcam_delayedwork_cancel);
    905 
    906 
    907 /*
    908  * Control related stuff
    909  */
    910 
    911 struct usbcam_ctrl *usbcam_ctrl_find(struct usbcam_dev *udp, u32 ctlid)
    912 {
    913 	struct usbcam_ctrl *ctrlp;
    914 
    915 	usbcam_chklock(udp);
    916 	list_for_each_entry(ctrlp, &udp->ud_ctrl_list, uc_links) {
    917 		if (ctrlp->uc_v4l.id == ctlid)
    918 			return ctrlp;
    919 	}
    920 	return NULL;
    921 }
    922 USBCAM_EXPORT_SYMBOL(usbcam_ctrl_find);
    923 
    924 int usbcam_ctrl_add(struct usbcam_dev *udp, struct usbcam_ctrl *ctrlp)
    925 {
    926 	int errors = 0;
    927 	struct usbcam_ctrl *xctrlp;
    928 
    929 	usbcam_chklock(udp);
    930 
    931 	/* Verify that the ID isn't already registered */
    932 	xctrlp = usbcam_ctrl_find(udp, ctrlp->uc_v4l.id);
    933 	if (xctrlp) {
    934 		usbcam_warn(udp, "control \"%s\" id=%d already defined",
    935 			    ctrlp->uc_v4l.name, ctrlp->uc_v4l.id);
    936 		errors++;
    937 	}
    938 
    939 	/* Check minimum, maximum, step, and default */
    940 	switch (ctrlp->uc_v4l.type) {
    941 	case V4L2_CTRL_TYPE_INTEGER:
    942 		if (ctrlp->uc_v4l.minimum > ctrlp->uc_v4l.maximum) {
    943 			usbcam_warn(udp, "control \"%s\" has "
    944 				    "minimum > maximum",
    945 				    ctrlp->uc_v4l.name);
    946 			errors++;
    947 		}
    948 		break;
    949 
    950 	case V4L2_CTRL_TYPE_BOOLEAN:
    951 		break;
    952 
    953 	case V4L2_CTRL_TYPE_MENU:
    954 		if (ctrlp->uc_v4l.minimum) {
    955 			usbcam_warn(udp, "control \"%s\" is MENU and has "
    956 				    "minimum != 0",
    957 				    ctrlp->uc_v4l.name);
    958 			errors++;
    959 		}
    960 		if (!ctrlp->uc_v4l.maximum) {
    961 			usbcam_warn(udp, "control \"%s\" is MENU and has "
    962 				    "maximum == 0",
    963 				    ctrlp->uc_v4l.name);
    964 				errors++;
    965 			}
    966 		if (!ctrlp->uc_menu_names) {
    967 			usbcam_warn(udp, "control \"%s\" is MENU and has "
    968 				    "NULL menu_names",
    969 				    ctrlp->uc_v4l.name);
    970 			errors++;
    971 			break;
    972 		}
    973 		break;
    974 
    975 	case V4L2_CTRL_TYPE_BUTTON:
    976 		if (ctrlp->uc_v4l.minimum) {
    977 			usbcam_warn(udp, "control \"%s\" is BUTTON "
    978 				    "and has minimum != 0",
    979 				    ctrlp->uc_v4l.name);
    980 			errors++;
    981 		}
    982 		if (ctrlp->uc_v4l.maximum) {
    983 			usbcam_warn(udp, "control \"%s\" is BUTTON "
    984 				    "and has maximum != 0",
    985 				    ctrlp->uc_v4l.name);
    986 			errors++;
    987 		}
    988 		if (ctrlp->uc_v4l.step) {
    989 			usbcam_warn(udp, "control \"%s\" is BUTTON "
    990 				    "and has step != 0",
    991 				    ctrlp->uc_v4l.name);
    992 			errors++;
    993 		}
    994 		break;
    995 
    996 	default:
    997 		usbcam_warn(udp, "control \"%s\" is of "
    998 			    "invalid type %d",
    999 			    ctrlp->uc_v4l.name,
   1000 			    ctrlp->uc_v4l.type);
   1001 		errors++;
   1002 	}
   1003 
   1004 	/* Check the range */
   1005 	if (ctrlp->uc_v4l.type == V4L2_CTRL_TYPE_BOOLEAN) {
   1006 		if ((ctrlp->uc_v4l.default_value != 0) &&
   1007 		    (ctrlp->uc_v4l.default_value != 1)) {
   1008 			usbcam_warn(udp, "control \"%s\" is BOOLEAN "
   1009 				    "and default value is %d",
   1010 				    ctrlp->uc_v4l.name,
   1011 				    ctrlp->uc_v4l.default_value);
   1012 			errors++;
   1013 		}
   1014 	}
   1015 
   1016 	else if ((ctrlp->uc_v4l.default_value <
   1017 		  ctrlp->uc_v4l.minimum) ||
   1018 		 (ctrlp->uc_v4l.default_value >
   1019 		  ctrlp->uc_v4l.maximum)) {
   1020 		usbcam_warn(udp, "control \"%s\" default out of range",
   1021 			    ctrlp->uc_v4l.name);
   1022 		errors++;
   1023 	}
   1024 
   1025 	/* Check the get_fn callout */
   1026 	if (ctrlp->uc_v4l.type == V4L2_CTRL_TYPE_BUTTON) {
   1027 		if (ctrlp->get_fn) {
   1028 			usbcam_warn(udp, "control \"%s\" is BUTTON "
   1029 				    "and has a get_fn callout",
   1030 				    ctrlp->uc_v4l.name);
   1031 			errors++;
   1032 		}
   1033 		if (!ctrlp->set_fn) {
   1034 			usbcam_warn(udp, "control \"%s\" is BUTTON "
   1035 				    "and has no set_fn callout",
   1036 				    ctrlp->uc_v4l.name);
   1037 			errors++;
   1038 		}
   1039 	}
   1040 
   1041 	if (errors)
   1042 		return -EINVAL;
   1043 
   1044 	list_add_tail(&ctrlp->uc_links, &udp->ud_ctrl_list);
   1045 	return 0;
   1046 }
   1047 USBCAM_EXPORT_SYMBOL(usbcam_ctrl_add);
   1048 
   1049 struct usbcam_ctrl *usbcam_ctrl_alloc(size_t real_size)
   1050 {
   1051 	struct usbcam_ctrl *ctrlp;
   1052 
   1053 	if (!real_size)
   1054 		real_size = sizeof(*ctrlp);
   1055 	if (real_size < sizeof(*ctrlp)) {
   1056 		printk(KERN_WARNING "Minidriver set control size %zd, "
   1057 		       "must be at least %zd\n", real_size, sizeof(*ctrlp));
   1058 		return NULL;
   1059 	}
   1060 
   1061 	ctrlp = kzalloc(real_size, GFP_KERNEL);
   1062 	if (!ctrlp)
   1063 		return NULL;
   1064 
   1065 	INIT_LIST_HEAD(&ctrlp->uc_links);
   1066 	return ctrlp;
   1067 }
   1068 USBCAM_EXPORT_SYMBOL(usbcam_ctrl_alloc);
   1069 
   1070 struct usbcam_ctrl *usbcam_ctrl_add_tmpl(struct usbcam_dev *udp,
   1071 					 const struct usbcam_ctrl *tmplp,
   1072 					 size_t real_size)
   1073 {
   1074 	struct usbcam_ctrl *ctrlp;
   1075 
   1076 	ctrlp = usbcam_ctrl_alloc(real_size);
   1077 	if (!ctrlp)
   1078 		return NULL;
   1079 
   1080 	memcpy(ctrlp, tmplp, real_size);
   1081 	INIT_LIST_HEAD(&ctrlp->uc_links);
   1082 
   1083 	if (usbcam_ctrl_add(udp, ctrlp)) {
   1084 		usbcam_ctrl_free(ctrlp);
   1085 		return NULL;
   1086 	}
   1087 
   1088 	return ctrlp;
   1089 }
   1090 USBCAM_EXPORT_SYMBOL(usbcam_ctrl_add_tmpl);
   1091 
   1092 void usbcam_ctrl_releaseall(struct usbcam_dev *udp)
   1093 {
   1094 	struct usbcam_ctrl *ctrlp;
   1095 	while (!list_empty(&udp->ud_ctrl_list)) {
   1096 		ctrlp = list_entry(udp->ud_ctrl_list.next,
   1097 				   struct usbcam_ctrl,
   1098 				   uc_links);
   1099 		list_del_init(&ctrlp->uc_links);
   1100 		if (ctrlp->release_fn)
   1101 			ctrlp->release_fn(udp, ctrlp);
   1102 		kfree(ctrlp);
   1103 	}
   1104 }
   1105 
   1106 
   1107 MODULE_DESCRIPTION("Abstraction Library for USB Webcam Drivers");
   1108 MODULE_AUTHOR("Sam Revitch <samr7 cs washington edu>");
   1109 MODULE_LICENSE("GPL");