aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/media/w9968cf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/media/w9968cf.c')
-rw-r--r--drivers/usb/media/w9968cf.c88
1 files changed, 45 insertions, 43 deletions
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index 9937fc64c8bf..b57dec3782e0 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -47,6 +47,13 @@
47#include "w9968cf.h" 47#include "w9968cf.h"
48#include "w9968cf_decoder.h" 48#include "w9968cf_decoder.h"
49 49
50static struct w9968cf_vpp_t* w9968cf_vpp;
51static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
52
53static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
54static DEFINE_MUTEX(w9968cf_devlist_mutex); /* semaphore for list traversal */
55
56static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */
50 57
51 58
52/**************************************************************************** 59/****************************************************************************
@@ -695,13 +702,12 @@ static int w9968cf_allocate_memory(struct w9968cf_device* cam)
695 /* Allocate memory for the isochronous transfer buffers */ 702 /* Allocate memory for the isochronous transfer buffers */
696 for (i = 0; i < W9968CF_URBS; i++) { 703 for (i = 0; i < W9968CF_URBS; i++) {
697 if (!(cam->transfer_buffer[i] = 704 if (!(cam->transfer_buffer[i] =
698 kmalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) { 705 kzalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
699 DBG(1, "Couldn't allocate memory for the isochronous " 706 DBG(1, "Couldn't allocate memory for the isochronous "
700 "transfer buffers (%u bytes)", 707 "transfer buffers (%u bytes)",
701 p_size * W9968CF_ISO_PACKETS) 708 p_size * W9968CF_ISO_PACKETS)
702 return -ENOMEM; 709 return -ENOMEM;
703 } 710 }
704 memset(cam->transfer_buffer[i], 0, W9968CF_ISO_PACKETS*p_size);
705 } 711 }
706 712
707 /* Allocate memory for the temporary frame buffer */ 713 /* Allocate memory for the temporary frame buffer */
@@ -2419,7 +2425,7 @@ w9968cf_configure_camera(struct w9968cf_device* cam,
2419 enum w9968cf_model_id mod_id, 2425 enum w9968cf_model_id mod_id,
2420 const unsigned short dev_nr) 2426 const unsigned short dev_nr)
2421{ 2427{
2422 init_MUTEX(&cam->fileop_sem); 2428 mutex_init(&cam->fileop_mutex);
2423 init_waitqueue_head(&cam->open); 2429 init_waitqueue_head(&cam->open);
2424 spin_lock_init(&cam->urb_lock); 2430 spin_lock_init(&cam->urb_lock);
2425 spin_lock_init(&cam->flist_lock); 2431 spin_lock_init(&cam->flist_lock);
@@ -2647,7 +2653,7 @@ static void w9968cf_adjust_configuration(struct w9968cf_device* cam)
2647 --------------------------------------------------------------------------*/ 2653 --------------------------------------------------------------------------*/
2648static void w9968cf_release_resources(struct w9968cf_device* cam) 2654static void w9968cf_release_resources(struct w9968cf_device* cam)
2649{ 2655{
2650 down(&w9968cf_devlist_sem); 2656 mutex_lock(&w9968cf_devlist_mutex);
2651 2657
2652 DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor) 2658 DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
2653 2659
@@ -2658,7 +2664,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam)
2658 kfree(cam->control_buffer); 2664 kfree(cam->control_buffer);
2659 kfree(cam->data_buffer); 2665 kfree(cam->data_buffer);
2660 2666
2661 up(&w9968cf_devlist_sem); 2667 mutex_unlock(&w9968cf_devlist_mutex);
2662} 2668}
2663 2669
2664 2670
@@ -2678,14 +2684,14 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
2678 2684
2679 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); 2685 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2680 2686
2681 down(&cam->dev_sem); 2687 mutex_lock(&cam->dev_mutex);
2682 2688
2683 if (cam->sensor == CC_UNKNOWN) { 2689 if (cam->sensor == CC_UNKNOWN) {
2684 DBG(2, "No supported image sensor has been detected by the " 2690 DBG(2, "No supported image sensor has been detected by the "
2685 "'ovcamchip' module for the %s (/dev/video%d). Make " 2691 "'ovcamchip' module for the %s (/dev/video%d). Make "
2686 "sure it is loaded *before* (re)connecting the camera.", 2692 "sure it is loaded *before* (re)connecting the camera.",
2687 symbolic(camlist, cam->id), cam->v4ldev->minor) 2693 symbolic(camlist, cam->id), cam->v4ldev->minor)
2688 up(&cam->dev_sem); 2694 mutex_unlock(&cam->dev_mutex);
2689 up_read(&w9968cf_disconnect); 2695 up_read(&w9968cf_disconnect);
2690 return -ENODEV; 2696 return -ENODEV;
2691 } 2697 }
@@ -2694,11 +2700,11 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
2694 DBG(2, "%s (/dev/video%d) has been already occupied by '%s'", 2700 DBG(2, "%s (/dev/video%d) has been already occupied by '%s'",
2695 symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command) 2701 symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
2696 if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) { 2702 if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
2697 up(&cam->dev_sem); 2703 mutex_unlock(&cam->dev_mutex);
2698 up_read(&w9968cf_disconnect); 2704 up_read(&w9968cf_disconnect);
2699 return -EWOULDBLOCK; 2705 return -EWOULDBLOCK;
2700 } 2706 }
2701 up(&cam->dev_sem); 2707 mutex_unlock(&cam->dev_mutex);
2702 err = wait_event_interruptible_exclusive(cam->open, 2708 err = wait_event_interruptible_exclusive(cam->open,
2703 cam->disconnected || 2709 cam->disconnected ||
2704 !cam->users); 2710 !cam->users);
@@ -2710,7 +2716,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
2710 up_read(&w9968cf_disconnect); 2716 up_read(&w9968cf_disconnect);
2711 return -ENODEV; 2717 return -ENODEV;
2712 } 2718 }
2713 down(&cam->dev_sem); 2719 mutex_lock(&cam->dev_mutex);
2714 } 2720 }
2715 2721
2716 DBG(5, "Opening '%s', /dev/video%d ...", 2722 DBG(5, "Opening '%s', /dev/video%d ...",
@@ -2739,7 +2745,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
2739 2745
2740 DBG(5, "Video device is open") 2746 DBG(5, "Video device is open")
2741 2747
2742 up(&cam->dev_sem); 2748 mutex_unlock(&cam->dev_mutex);
2743 up_read(&w9968cf_disconnect); 2749 up_read(&w9968cf_disconnect);
2744 2750
2745 return 0; 2751 return 0;
@@ -2747,7 +2753,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
2747deallocate_memory: 2753deallocate_memory:
2748 w9968cf_deallocate_memory(cam); 2754 w9968cf_deallocate_memory(cam);
2749 DBG(2, "Failed to open the video device") 2755 DBG(2, "Failed to open the video device")
2750 up(&cam->dev_sem); 2756 mutex_unlock(&cam->dev_mutex);
2751 up_read(&w9968cf_disconnect); 2757 up_read(&w9968cf_disconnect);
2752 return err; 2758 return err;
2753} 2759}
@@ -2759,13 +2765,13 @@ static int w9968cf_release(struct inode* inode, struct file* filp)
2759 2765
2760 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); 2766 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2761 2767
2762 down(&cam->dev_sem); /* prevent disconnect() to be called */ 2768 mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */
2763 2769
2764 w9968cf_stop_transfer(cam); 2770 w9968cf_stop_transfer(cam);
2765 2771
2766 if (cam->disconnected) { 2772 if (cam->disconnected) {
2767 w9968cf_release_resources(cam); 2773 w9968cf_release_resources(cam);
2768 up(&cam->dev_sem); 2774 mutex_unlock(&cam->dev_mutex);
2769 kfree(cam); 2775 kfree(cam);
2770 return 0; 2776 return 0;
2771 } 2777 }
@@ -2775,7 +2781,7 @@ static int w9968cf_release(struct inode* inode, struct file* filp)
2775 wake_up_interruptible_nr(&cam->open, 1); 2781 wake_up_interruptible_nr(&cam->open, 1);
2776 2782
2777 DBG(5, "Video device closed") 2783 DBG(5, "Video device closed")
2778 up(&cam->dev_sem); 2784 mutex_unlock(&cam->dev_mutex);
2779 return 0; 2785 return 0;
2780} 2786}
2781 2787
@@ -2792,18 +2798,18 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2792 if (filp->f_flags & O_NONBLOCK) 2798 if (filp->f_flags & O_NONBLOCK)
2793 return -EWOULDBLOCK; 2799 return -EWOULDBLOCK;
2794 2800
2795 if (down_interruptible(&cam->fileop_sem)) 2801 if (mutex_lock_interruptible(&cam->fileop_mutex))
2796 return -ERESTARTSYS; 2802 return -ERESTARTSYS;
2797 2803
2798 if (cam->disconnected) { 2804 if (cam->disconnected) {
2799 DBG(2, "Device not present") 2805 DBG(2, "Device not present")
2800 up(&cam->fileop_sem); 2806 mutex_unlock(&cam->fileop_mutex);
2801 return -ENODEV; 2807 return -ENODEV;
2802 } 2808 }
2803 2809
2804 if (cam->misconfigured) { 2810 if (cam->misconfigured) {
2805 DBG(2, "The camera is misconfigured. Close and open it again.") 2811 DBG(2, "The camera is misconfigured. Close and open it again.")
2806 up(&cam->fileop_sem); 2812 mutex_unlock(&cam->fileop_mutex);
2807 return -EIO; 2813 return -EIO;
2808 } 2814 }
2809 2815
@@ -2818,11 +2824,11 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2818 cam->frame[1].status == F_READY || 2824 cam->frame[1].status == F_READY ||
2819 cam->disconnected); 2825 cam->disconnected);
2820 if (err) { 2826 if (err) {
2821 up(&cam->fileop_sem); 2827 mutex_unlock(&cam->fileop_mutex);
2822 return err; 2828 return err;
2823 } 2829 }
2824 if (cam->disconnected) { 2830 if (cam->disconnected) {
2825 up(&cam->fileop_sem); 2831 mutex_unlock(&cam->fileop_mutex);
2826 return -ENODEV; 2832 return -ENODEV;
2827 } 2833 }
2828 2834
@@ -2836,7 +2842,7 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2836 2842
2837 if (copy_to_user(buf, fr->buffer, count)) { 2843 if (copy_to_user(buf, fr->buffer, count)) {
2838 fr->status = F_UNUSED; 2844 fr->status = F_UNUSED;
2839 up(&cam->fileop_sem); 2845 mutex_unlock(&cam->fileop_mutex);
2840 return -EFAULT; 2846 return -EFAULT;
2841 } 2847 }
2842 *f_pos += count; 2848 *f_pos += count;
@@ -2845,7 +2851,7 @@ w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
2845 2851
2846 DBG(5, "%zu bytes read", count) 2852 DBG(5, "%zu bytes read", count)
2847 2853
2848 up(&cam->fileop_sem); 2854 mutex_unlock(&cam->fileop_mutex);
2849 return count; 2855 return count;
2850} 2856}
2851 2857
@@ -2899,24 +2905,24 @@ w9968cf_ioctl(struct inode* inode, struct file* filp,
2899 2905
2900 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); 2906 cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
2901 2907
2902 if (down_interruptible(&cam->fileop_sem)) 2908 if (mutex_lock_interruptible(&cam->fileop_mutex))
2903 return -ERESTARTSYS; 2909 return -ERESTARTSYS;
2904 2910
2905 if (cam->disconnected) { 2911 if (cam->disconnected) {
2906 DBG(2, "Device not present") 2912 DBG(2, "Device not present")
2907 up(&cam->fileop_sem); 2913 mutex_unlock(&cam->fileop_mutex);
2908 return -ENODEV; 2914 return -ENODEV;
2909 } 2915 }
2910 2916
2911 if (cam->misconfigured) { 2917 if (cam->misconfigured) {
2912 DBG(2, "The camera is misconfigured. Close and open it again.") 2918 DBG(2, "The camera is misconfigured. Close and open it again.")
2913 up(&cam->fileop_sem); 2919 mutex_unlock(&cam->fileop_mutex);
2914 return -EIO; 2920 return -EIO;
2915 } 2921 }
2916 2922
2917 err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg); 2923 err = w9968cf_v4l_ioctl(inode, filp, cmd, (void __user *)arg);
2918 2924
2919 up(&cam->fileop_sem); 2925 mutex_unlock(&cam->fileop_mutex);
2920 return err; 2926 return err;
2921} 2927}
2922 2928
@@ -3499,14 +3505,12 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3499 return -ENODEV; 3505 return -ENODEV;
3500 3506
3501 cam = (struct w9968cf_device*) 3507 cam = (struct w9968cf_device*)
3502 kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL); 3508 kzalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
3503 if (!cam) 3509 if (!cam)
3504 return -ENOMEM; 3510 return -ENOMEM;
3505 3511
3506 memset(cam, 0, sizeof(*cam)); 3512 mutex_init(&cam->dev_mutex);
3507 3513 mutex_lock(&cam->dev_mutex);
3508 init_MUTEX(&cam->dev_sem);
3509 down(&cam->dev_sem);
3510 3514
3511 cam->usbdev = udev; 3515 cam->usbdev = udev;
3512 /* NOTE: a local copy is used to avoid possible race conditions */ 3516 /* NOTE: a local copy is used to avoid possible race conditions */
@@ -3518,10 +3522,10 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3518 simcams = W9968CF_SIMCAMS; 3522 simcams = W9968CF_SIMCAMS;
3519 3523
3520 /* How many cameras are connected ? */ 3524 /* How many cameras are connected ? */
3521 down(&w9968cf_devlist_sem); 3525 mutex_lock(&w9968cf_devlist_mutex);
3522 list_for_each(ptr, &w9968cf_dev_list) 3526 list_for_each(ptr, &w9968cf_dev_list)
3523 sc++; 3527 sc++;
3524 up(&w9968cf_devlist_sem); 3528 mutex_unlock(&w9968cf_devlist_mutex);
3525 3529
3526 if (sc >= simcams) { 3530 if (sc >= simcams) {
3527 DBG(2, "Device rejected: too many connected cameras " 3531 DBG(2, "Device rejected: too many connected cameras "
@@ -3532,21 +3536,19 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3532 3536
3533 3537
3534 /* Allocate 2 bytes of memory for camera control USB transfers */ 3538 /* Allocate 2 bytes of memory for camera control USB transfers */
3535 if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) { 3539 if (!(cam->control_buffer = kzalloc(2, GFP_KERNEL))) {
3536 DBG(1,"Couldn't allocate memory for camera control transfers") 3540 DBG(1,"Couldn't allocate memory for camera control transfers")
3537 err = -ENOMEM; 3541 err = -ENOMEM;
3538 goto fail; 3542 goto fail;
3539 } 3543 }
3540 memset(cam->control_buffer, 0, 2);
3541 3544
3542 /* Allocate 8 bytes of memory for USB data transfers to the FSB */ 3545 /* Allocate 8 bytes of memory for USB data transfers to the FSB */
3543 if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) { 3546 if (!(cam->data_buffer = kzalloc(8, GFP_KERNEL))) {
3544 DBG(1, "Couldn't allocate memory for data " 3547 DBG(1, "Couldn't allocate memory for data "
3545 "transfers to the FSB") 3548 "transfers to the FSB")
3546 err = -ENOMEM; 3549 err = -ENOMEM;
3547 goto fail; 3550 goto fail;
3548 } 3551 }
3549 memset(cam->data_buffer, 0, 8);
3550 3552
3551 /* Register the V4L device */ 3553 /* Register the V4L device */
3552 cam->v4ldev = video_device_alloc(); 3554 cam->v4ldev = video_device_alloc();
@@ -3583,9 +3585,9 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3583 w9968cf_configure_camera(cam, udev, mod_id, dev_nr); 3585 w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
3584 3586
3585 /* Add a new entry into the list of V4L registered devices */ 3587 /* Add a new entry into the list of V4L registered devices */
3586 down(&w9968cf_devlist_sem); 3588 mutex_lock(&w9968cf_devlist_mutex);
3587 list_add(&cam->v4llist, &w9968cf_dev_list); 3589 list_add(&cam->v4llist, &w9968cf_dev_list);
3588 up(&w9968cf_devlist_sem); 3590 mutex_unlock(&w9968cf_devlist_mutex);
3589 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0; 3591 dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
3590 3592
3591 w9968cf_turn_on_led(cam); 3593 w9968cf_turn_on_led(cam);
@@ -3593,7 +3595,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3593 w9968cf_i2c_init(cam); 3595 w9968cf_i2c_init(cam);
3594 3596
3595 usb_set_intfdata(intf, cam); 3597 usb_set_intfdata(intf, cam);
3596 up(&cam->dev_sem); 3598 mutex_unlock(&cam->dev_mutex);
3597 return 0; 3599 return 0;
3598 3600
3599fail: /* Free unused memory */ 3601fail: /* Free unused memory */
@@ -3601,7 +3603,7 @@ fail: /* Free unused memory */
3601 kfree(cam->data_buffer); 3603 kfree(cam->data_buffer);
3602 if (cam->v4ldev) 3604 if (cam->v4ldev)
3603 video_device_release(cam->v4ldev); 3605 video_device_release(cam->v4ldev);
3604 up(&cam->dev_sem); 3606 mutex_unlock(&cam->dev_mutex);
3605 kfree(cam); 3607 kfree(cam);
3606 return err; 3608 return err;
3607} 3609}
@@ -3616,7 +3618,7 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
3616 3618
3617 if (cam) { 3619 if (cam) {
3618 /* Prevent concurrent accesses to data */ 3620 /* Prevent concurrent accesses to data */
3619 down(&cam->dev_sem); 3621 mutex_lock(&cam->dev_mutex);
3620 3622
3621 cam->disconnected = 1; 3623 cam->disconnected = 1;
3622 3624
@@ -3635,7 +3637,7 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
3635 } else 3637 } else
3636 w9968cf_release_resources(cam); 3638 w9968cf_release_resources(cam);
3637 3639
3638 up(&cam->dev_sem); 3640 mutex_unlock(&cam->dev_mutex);
3639 3641
3640 if (!cam->users) 3642 if (!cam->users)
3641 kfree(cam); 3643 kfree(cam);