aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Ellingsworth <david@identd.dyndns.org>2008-09-21 03:12:03 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-12 07:37:08 -0400
commit4aaec3ea41addf6fe4fe029aa535f3c019ee0e6d (patch)
treecaa372c064a2dacea481c0fd15ea28bf188e05fe
parent714b9a1e0ae3224728d1d96d77150ceea7487a61 (diff)
V4L/DVB (9034): With the recent patch to v4l2 titled "v4l2: use register_chrdev_region
instead of register_chrdev", the internal reference count is no longer necessary in order to free the internal stk_webcam struct. This patch removes the reference counter from the stk_webcam struct and frees the struct via the video_device release callback. It also fixes an associated bug in stk_camera_probe which could result from video_unregister_device being called before video_register_device. Lastly, it simplifies access to the stk_webcam struct in several places. This patch should apply cleanly against the "working" branch of the v4l-dvb git repository. This patch is identical to the patch I sent a couple of months back titled "stk-webcam: Fix video_device handling" except that it has been rebased against current modifications to stk-webcam and it no longer depends on any other outstanding patches. Acked-by: Jaime Velasco Juan <jsagarribay@gmail.com> Signed-off-by: David Ellingsworth <david@identd.dyndns.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/stk-webcam.c84
-rw-r--r--drivers/media/video/stk-webcam.h2
2 files changed, 23 insertions, 63 deletions
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index 8dda5680094d..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 video_set_drvdata(&dev->vdev, 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 */
@@ -694,8 +678,7 @@ static int v4l_stk_open(struct inode *inode, struct file *fp)
694 unlock_kernel(); 678 unlock_kernel();
695 return -ENXIO; 679 return -ENXIO;
696 } 680 }
697 fp->private_data = vdev; 681 fp->private_data = dev;
698 kref_get(&dev->kref);
699 usb_autopm_get_interface(dev->interface); 682 usb_autopm_get_interface(dev->interface);
700 unlock_kernel(); 683 unlock_kernel();
701 684
@@ -704,23 +687,10 @@ static int v4l_stk_open(struct inode *inode, struct file *fp)
704 687
705static int v4l_stk_release(struct inode *inode, struct file *fp) 688static int v4l_stk_release(struct inode *inode, struct file *fp)
706{ 689{
707 struct stk_camera *dev; 690 struct stk_camera *dev = fp->private_data;
708 struct video_device *vdev;
709
710 vdev = video_devdata(fp);
711 if (vdev == NULL) {
712 STK_ERROR("v4l_release called w/o video devdata\n");
713 return -EFAULT;
714 }
715 dev = vdev_to_camera(vdev);
716 if (dev == NULL) {
717 STK_ERROR("v4l_release called on removed device\n");
718 return -ENODEV;
719 }
720 691
721 if (dev->owner != fp) { 692 if (dev->owner != fp) {
722 usb_autopm_put_interface(dev->interface); 693 usb_autopm_put_interface(dev->interface);
723 kref_put(&dev->kref, stk_camera_cleanup);
724 return 0; 694 return 0;
725 } 695 }
726 696
@@ -731,7 +701,6 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
731 dev->owner = NULL; 701 dev->owner = NULL;
732 702
733 usb_autopm_put_interface(dev->interface); 703 usb_autopm_put_interface(dev->interface);
734 kref_put(&dev->kref, stk_camera_cleanup);
735 704
736 return 0; 705 return 0;
737} 706}
@@ -742,14 +711,8 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
742 int i; 711 int i;
743 int ret; 712 int ret;
744 unsigned long flags; 713 unsigned long flags;
745 struct stk_camera *dev;
746 struct video_device *vdev;
747 struct stk_sio_buffer *sbuf; 714 struct stk_sio_buffer *sbuf;
748 715 struct stk_camera *dev = fp->private_data;
749 vdev = video_devdata(fp);
750 if (vdev == NULL)
751 return -EFAULT;
752 dev = vdev_to_camera(vdev);
753 716
754 if (dev == NULL) 717 if (dev == NULL)
755 return -EIO; 718 return -EIO;
@@ -808,15 +771,8 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
808 771
809static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait) 772static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait)
810{ 773{
811 struct stk_camera *dev; 774 struct stk_camera *dev = fp->private_data;
812 struct video_device *vdev;
813
814 vdev = video_devdata(fp);
815
816 if (vdev == NULL)
817 return -EFAULT;
818 775
819 dev = vdev_to_camera(vdev);
820 if (dev == NULL) 776 if (dev == NULL)
821 return -ENODEV; 777 return -ENODEV;
822 778
@@ -854,16 +810,12 @@ static int v4l_stk_mmap(struct file *fp, struct vm_area_struct *vma)
854 unsigned int i; 810 unsigned int i;
855 int ret; 811 int ret;
856 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 812 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
857 struct stk_camera *dev; 813 struct stk_camera *dev = fp->private_data;
858 struct video_device *vdev;
859 struct stk_sio_buffer *sbuf = NULL; 814 struct stk_sio_buffer *sbuf = NULL;
860 815
861 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) 816 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
862 return -EINVAL; 817 return -EINVAL;
863 818
864 vdev = video_devdata(fp);
865 dev = vdev_to_camera(vdev);
866
867 for (i = 0; i < dev->n_sbufs; i++) { 819 for (i = 0; i < dev->n_sbufs; i++) {
868 if (dev->sio_bufs[i].v4lbuf.m.offset == offset) { 820 if (dev->sio_bufs[i].v4lbuf.m.offset == offset) {
869 sbuf = dev->sio_bufs + i; 821 sbuf = dev->sio_bufs + i;
@@ -1359,6 +1311,12 @@ static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = {
1359 1311
1360static void stk_v4l_dev_release(struct video_device *vd) 1312static void stk_v4l_dev_release(struct video_device *vd)
1361{ 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);
1362} 1320}
1363 1321
1364static struct video_device stk_v4l_data = { 1322static struct video_device stk_v4l_data = {
@@ -1379,7 +1337,6 @@ static int stk_register_video_device(struct stk_camera *dev)
1379 dev->vdev = stk_v4l_data; 1337 dev->vdev = stk_v4l_data;
1380 dev->vdev.debug = debug; 1338 dev->vdev.debug = debug;
1381 dev->vdev.parent = &dev->interface->dev; 1339 dev->vdev.parent = &dev->interface->dev;
1382 video_set_drvdata(&dev->vdev, dev);
1383 err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1); 1340 err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);
1384 if (err) 1341 if (err)
1385 STK_ERROR("v4l registration failed\n"); 1342 STK_ERROR("v4l registration failed\n");
@@ -1396,7 +1353,7 @@ static int stk_camera_probe(struct usb_interface *interface,
1396 const struct usb_device_id *id) 1353 const struct usb_device_id *id)
1397{ 1354{
1398 int i; 1355 int i;
1399 int err; 1356 int err = 0;
1400 1357
1401 struct stk_camera *dev = NULL; 1358 struct stk_camera *dev = NULL;
1402 struct usb_device *udev = interface_to_usbdev(interface); 1359 struct usb_device *udev = interface_to_usbdev(interface);
@@ -1409,7 +1366,6 @@ static int stk_camera_probe(struct usb_interface *interface,
1409 return -ENOMEM; 1366 return -ENOMEM;
1410 } 1367 }
1411 1368
1412 kref_init(&dev->kref);
1413 spin_lock_init(&dev->spinlock); 1369 spin_lock_init(&dev->spinlock);
1414 init_waitqueue_head(&dev->wait_frame); 1370 init_waitqueue_head(&dev->wait_frame);
1415 1371
@@ -1442,8 +1398,8 @@ static int stk_camera_probe(struct usb_interface *interface,
1442 } 1398 }
1443 if (!dev->isoc_ep) { 1399 if (!dev->isoc_ep) {
1444 STK_ERROR("Could not find isoc-in endpoint"); 1400 STK_ERROR("Could not find isoc-in endpoint");
1445 kref_put(&dev->kref, stk_camera_cleanup); 1401 err = -ENODEV;
1446 return -ENODEV; 1402 goto error;
1447 } 1403 }
1448 dev->vsettings.brightness = 0x7fff; 1404 dev->vsettings.brightness = 0x7fff;
1449 dev->vsettings.palette = V4L2_PIX_FMT_RGB565; 1405 dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
@@ -1457,14 +1413,17 @@ static int stk_camera_probe(struct usb_interface *interface,
1457 1413
1458 err = stk_register_video_device(dev); 1414 err = stk_register_video_device(dev);
1459 if (err) { 1415 if (err) {
1460 kref_put(&dev->kref, stk_camera_cleanup); 1416 goto error;
1461 return err;
1462 } 1417 }
1463 1418
1464 stk_create_sysfs_files(&dev->vdev); 1419 stk_create_sysfs_files(&dev->vdev);
1465 usb_autopm_enable(dev->interface); 1420 usb_autopm_enable(dev->interface);
1466 1421
1467 return 0; 1422 return 0;
1423
1424error:
1425 kfree(dev);
1426 return err;
1468} 1427}
1469 1428
1470static void stk_camera_disconnect(struct usb_interface *interface) 1429static void stk_camera_disconnect(struct usb_interface *interface)
@@ -1477,7 +1436,10 @@ static void stk_camera_disconnect(struct usb_interface *interface)
1477 wake_up_interruptible(&dev->wait_frame); 1436 wake_up_interruptible(&dev->wait_frame);
1478 stk_remove_sysfs_files(&dev->vdev); 1437 stk_remove_sysfs_files(&dev->vdev);
1479 1438
1480 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);
1481} 1443}
1482 1444
1483#ifdef CONFIG_PM 1445#ifdef CONFIG_PM
diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h
index df4dfefc5327..084a85bdd16e 100644
--- a/drivers/media/video/stk-webcam.h
+++ b/drivers/media/video/stk-webcam.h
@@ -99,7 +99,6 @@ struct stk_camera {
99 99
100 u8 isoc_ep; 100 u8 isoc_ep;
101 101
102 struct kref kref;
103 /* Not sure if this is right */ 102 /* Not sure if this is right */
104 atomic_t urbs_used; 103 atomic_t urbs_used;
105 104
@@ -121,7 +120,6 @@ struct stk_camera {
121 unsigned sequence; 120 unsigned sequence;
122}; 121};
123 122
124#define to_stk_camera(d) container_of(d, struct stk_camera, kref)
125#define vdev_to_camera(d) container_of(d, struct stk_camera, vdev) 123#define vdev_to_camera(d) container_of(d, struct stk_camera, vdev)
126 124
127void stk_camera_delete(struct kref *); 125void stk_camera_delete(struct kref *);