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");