aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/stk-webcam.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/stk-webcam.c')
-rw-r--r--drivers/media/video/stk-webcam.c90
1 files changed, 28 insertions, 62 deletions
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index ad36af30e099..db69bc5556d6 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -65,22 +65,6 @@ static struct usb_device_id stkwebcam_table[] = {
65}; 65};
66MODULE_DEVICE_TABLE(usb, stkwebcam_table); 66MODULE_DEVICE_TABLE(usb, stkwebcam_table);
67 67
68static void stk_camera_cleanup(struct kref *kref)
69{
70 struct stk_camera *dev = to_stk_camera(kref);
71
72 STK_INFO("Syntek USB2.0 Camera release resources"
73 " video device /dev/video%d\n", dev->vdev.minor);
74 video_unregister_device(&dev->vdev);
75 dev->vdev.priv = NULL;
76
77 if (dev->sio_bufs != NULL || dev->isobufs != NULL)
78 STK_ERROR("We are leaking memory\n");
79 usb_put_intf(dev->interface);
80 kfree(dev);
81}
82
83
84/* 68/*
85 * Basic stuff 69 * Basic stuff
86 */ 70 */
@@ -689,34 +673,24 @@ static int v4l_stk_open(struct inode *inode, struct file *fp)
689 vdev = video_devdata(fp); 673 vdev = video_devdata(fp);
690 dev = vdev_to_camera(vdev); 674 dev = vdev_to_camera(vdev);
691 675
692 if (dev == NULL || !is_present(dev)) 676 lock_kernel();
677 if (dev == NULL || !is_present(dev)) {
678 unlock_kernel();
693 return -ENXIO; 679 return -ENXIO;
694 fp->private_data = vdev; 680 }
695 kref_get(&dev->kref); 681 fp->private_data = dev;
696 usb_autopm_get_interface(dev->interface); 682 usb_autopm_get_interface(dev->interface);
683 unlock_kernel();
697 684
698 return 0; 685 return 0;
699} 686}
700 687
701static int v4l_stk_release(struct inode *inode, struct file *fp) 688static int v4l_stk_release(struct inode *inode, struct file *fp)
702{ 689{
703 struct stk_camera *dev; 690 struct stk_camera *dev = fp->private_data;
704 struct video_device *vdev;
705
706 vdev = video_devdata(fp);
707 if (vdev == NULL) {
708 STK_ERROR("v4l_release called w/o video devdata\n");
709 return -EFAULT;
710 }
711 dev = vdev_to_camera(vdev);
712 if (dev == NULL) {
713 STK_ERROR("v4l_release called on removed device\n");
714 return -ENODEV;
715 }
716 691
717 if (dev->owner != fp) { 692 if (dev->owner != fp) {
718 usb_autopm_put_interface(dev->interface); 693 usb_autopm_put_interface(dev->interface);
719 kref_put(&dev->kref, stk_camera_cleanup);
720 return 0; 694 return 0;
721 } 695 }
722 696
@@ -727,7 +701,6 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
727 dev->owner = NULL; 701 dev->owner = NULL;
728 702
729 usb_autopm_put_interface(dev->interface); 703 usb_autopm_put_interface(dev->interface);
730 kref_put(&dev->kref, stk_camera_cleanup);
731 704
732 return 0; 705 return 0;
733} 706}
@@ -738,14 +711,8 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
738 int i; 711 int i;
739 int ret; 712 int ret;
740 unsigned long flags; 713 unsigned long flags;
741 struct stk_camera *dev;
742 struct video_device *vdev;
743 struct stk_sio_buffer *sbuf; 714 struct stk_sio_buffer *sbuf;
744 715 struct stk_camera *dev = fp->private_data;
745 vdev = video_devdata(fp);
746 if (vdev == NULL)
747 return -EFAULT;
748 dev = vdev_to_camera(vdev);
749 716
750 if (dev == NULL) 717 if (dev == NULL)
751 return -EIO; 718 return -EIO;
@@ -804,15 +771,8 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
804 771
805static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait) 772static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait)
806{ 773{
807 struct stk_camera *dev; 774 struct stk_camera *dev = fp->private_data;
808 struct video_device *vdev;
809
810 vdev = video_devdata(fp);
811
812 if (vdev == NULL)
813 return -EFAULT;
814 775
815 dev = vdev_to_camera(vdev);
816 if (dev == NULL) 776 if (dev == NULL)
817 return -ENODEV; 777 return -ENODEV;
818 778
@@ -850,16 +810,12 @@ static int v4l_stk_mmap(struct file *fp, struct vm_area_struct *vma)
850 unsigned int i; 810 unsigned int i;
851 int ret; 811 int ret;
852 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 812 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
853 struct stk_camera *dev; 813 struct stk_camera *dev = fp->private_data;
854 struct video_device *vdev;
855 struct stk_sio_buffer *sbuf = NULL; 814 struct stk_sio_buffer *sbuf = NULL;
856 815
857 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) 816 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
858 return -EINVAL; 817 return -EINVAL;
859 818
860 vdev = video_devdata(fp);
861 dev = vdev_to_camera(vdev);
862
863 for (i = 0; i < dev->n_sbufs; i++) { 819 for (i = 0; i < dev->n_sbufs; i++) {
864 if (dev->sio_bufs[i].v4lbuf.m.offset == offset) { 820 if (dev->sio_bufs[i].v4lbuf.m.offset == offset) {
865 sbuf = dev->sio_bufs + i; 821 sbuf = dev->sio_bufs + i;
@@ -1355,6 +1311,12 @@ static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = {
1355 1311
1356static void stk_v4l_dev_release(struct video_device *vd) 1312static void stk_v4l_dev_release(struct video_device *vd)
1357{ 1313{
1314 struct stk_camera *dev = vdev_to_camera(vd);
1315
1316 if (dev->sio_bufs != NULL || dev->isobufs != NULL)
1317 STK_ERROR("We are leaking memory\n");
1318 usb_put_intf(dev->interface);
1319 kfree(dev);
1358} 1320}
1359 1321
1360static struct video_device stk_v4l_data = { 1322static struct video_device stk_v4l_data = {
@@ -1375,7 +1337,6 @@ static int stk_register_video_device(struct stk_camera *dev)
1375 dev->vdev = stk_v4l_data; 1337 dev->vdev = stk_v4l_data;
1376 dev->vdev.debug = debug; 1338 dev->vdev.debug = debug;
1377 dev->vdev.parent = &dev->interface->dev; 1339 dev->vdev.parent = &dev->interface->dev;
1378 dev->vdev.priv = dev;
1379 err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1); 1340 err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);
1380 if (err) 1341 if (err)
1381 STK_ERROR("v4l registration failed\n"); 1342 STK_ERROR("v4l registration failed\n");
@@ -1392,7 +1353,7 @@ static int stk_camera_probe(struct usb_interface *interface,
1392 const struct usb_device_id *id) 1353 const struct usb_device_id *id)
1393{ 1354{
1394 int i; 1355 int i;
1395 int err; 1356 int err = 0;
1396 1357
1397 struct stk_camera *dev = NULL; 1358 struct stk_camera *dev = NULL;
1398 struct usb_device *udev = interface_to_usbdev(interface); 1359 struct usb_device *udev = interface_to_usbdev(interface);
@@ -1405,7 +1366,6 @@ static int stk_camera_probe(struct usb_interface *interface,
1405 return -ENOMEM; 1366 return -ENOMEM;
1406 } 1367 }
1407 1368
1408 kref_init(&dev->kref);
1409 spin_lock_init(&dev->spinlock); 1369 spin_lock_init(&dev->spinlock);
1410 init_waitqueue_head(&dev->wait_frame); 1370 init_waitqueue_head(&dev->wait_frame);
1411 1371
@@ -1438,8 +1398,8 @@ static int stk_camera_probe(struct usb_interface *interface,
1438 } 1398 }
1439 if (!dev->isoc_ep) { 1399 if (!dev->isoc_ep) {
1440 STK_ERROR("Could not find isoc-in endpoint"); 1400 STK_ERROR("Could not find isoc-in endpoint");
1441 kref_put(&dev->kref, stk_camera_cleanup); 1401 err = -ENODEV;
1442 return -ENODEV; 1402 goto error;
1443 } 1403 }
1444 dev->vsettings.brightness = 0x7fff; 1404 dev->vsettings.brightness = 0x7fff;
1445 dev->vsettings.palette = V4L2_PIX_FMT_RGB565; 1405 dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
@@ -1453,14 +1413,17 @@ static int stk_camera_probe(struct usb_interface *interface,
1453 1413
1454 err = stk_register_video_device(dev); 1414 err = stk_register_video_device(dev);
1455 if (err) { 1415 if (err) {
1456 kref_put(&dev->kref, stk_camera_cleanup); 1416 goto error;
1457 return err;
1458 } 1417 }
1459 1418
1460 stk_create_sysfs_files(&dev->vdev); 1419 stk_create_sysfs_files(&dev->vdev);
1461 usb_autopm_enable(dev->interface); 1420 usb_autopm_enable(dev->interface);
1462 1421
1463 return 0; 1422 return 0;
1423
1424error:
1425 kfree(dev);
1426 return err;
1464} 1427}
1465 1428
1466static void stk_camera_disconnect(struct usb_interface *interface) 1429static void stk_camera_disconnect(struct usb_interface *interface)
@@ -1473,7 +1436,10 @@ static void stk_camera_disconnect(struct usb_interface *interface)
1473 wake_up_interruptible(&dev->wait_frame); 1436 wake_up_interruptible(&dev->wait_frame);
1474 stk_remove_sysfs_files(&dev->vdev); 1437 stk_remove_sysfs_files(&dev->vdev);
1475 1438
1476 kref_put(&dev->kref, stk_camera_cleanup); 1439 STK_INFO("Syntek USB2.0 Camera release resources"
1440 "video device /dev/video%d\n", dev->vdev.minor);
1441
1442 video_unregister_device(&dev->vdev);
1477} 1443}
1478 1444
1479#ifdef CONFIG_PM 1445#ifdef CONFIG_PM