aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-11-19 04:37:53 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-11-24 09:01:38 -0500
commite07a1d8ab20a059fefbfd1558db43701bca560d7 (patch)
tree834a4dc09da2e86ecbab2ce7ae4a5e2b298ebfd6
parent5c4fa002b1c7b40f65fa911ae17a823ec9e26ab2 (diff)
V4L/DVB (9691): gspca: Move the video device to a separate area.
The video device was part of the gspca device. On device disconnection while streaming, the device structure is freed at close time. In this case, the remaining close job on the video device run out of allocated memory. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/gspca.c28
-rw-r--r--drivers/media/video/gspca/gspca.h2
2 files changed, 14 insertions, 16 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index a565f3764837..748a87e82e44 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -862,7 +862,7 @@ static int dev_open(struct inode *inode, struct file *file)
862 int ret; 862 int ret;
863 863
864 PDEBUG(D_STREAM, "%s open", current->comm); 864 PDEBUG(D_STREAM, "%s open", current->comm);
865 gspca_dev = (struct gspca_dev *) video_devdata(file); 865 gspca_dev = video_drvdata(file);
866 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 866 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
867 return -ERESTARTSYS; 867 return -ERESTARTSYS;
868 if (!gspca_dev->present) { 868 if (!gspca_dev->present) {
@@ -890,10 +890,10 @@ static int dev_open(struct inode *inode, struct file *file)
890#ifdef GSPCA_DEBUG 890#ifdef GSPCA_DEBUG
891 /* activate the v4l2 debug */ 891 /* activate the v4l2 debug */
892 if (gspca_debug & D_V4L2) 892 if (gspca_debug & D_V4L2)
893 gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL 893 gspca_dev->vdev->debug |= V4L2_DEBUG_IOCTL
894 | V4L2_DEBUG_IOCTL_ARG; 894 | V4L2_DEBUG_IOCTL_ARG;
895 else 895 else
896 gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL 896 gspca_dev->vdev->debug &= ~(V4L2_DEBUG_IOCTL
897 | V4L2_DEBUG_IOCTL_ARG); 897 | V4L2_DEBUG_IOCTL_ARG);
898#endif 898#endif
899 ret = 0; 899 ret = 0;
@@ -1755,11 +1755,6 @@ out:
1755 return ret; 1755 return ret;
1756} 1756}
1757 1757
1758static void dev_release(struct video_device *vfd)
1759{
1760 /* nothing */
1761}
1762
1763static struct file_operations dev_fops = { 1758static struct file_operations dev_fops = {
1764 .owner = THIS_MODULE, 1759 .owner = THIS_MODULE,
1765 .open = dev_open, 1760 .open = dev_open,
@@ -1807,7 +1802,7 @@ static struct video_device gspca_template = {
1807 .name = "gspca main driver", 1802 .name = "gspca main driver",
1808 .fops = &dev_fops, 1803 .fops = &dev_fops,
1809 .ioctl_ops = &dev_ioctl_ops, 1804 .ioctl_ops = &dev_ioctl_ops,
1810 .release = dev_release, /* mandatory */ 1805 .release = video_device_release,
1811 .minor = -1, 1806 .minor = -1,
1812}; 1807};
1813 1808
@@ -1876,16 +1871,18 @@ int gspca_dev_probe(struct usb_interface *intf,
1876 init_waitqueue_head(&gspca_dev->wq); 1871 init_waitqueue_head(&gspca_dev->wq);
1877 1872
1878 /* init video stuff */ 1873 /* init video stuff */
1879 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); 1874 gspca_dev->vdev = video_device_alloc();
1880 gspca_dev->vdev.parent = &dev->dev; 1875 memcpy(gspca_dev->vdev, &gspca_template, sizeof gspca_template);
1881 gspca_dev->vdev.fops = &dev_fops; 1876 gspca_dev->vdev->parent = &dev->dev;
1882 gspca_dev->module = module; 1877 gspca_dev->module = module;
1883 gspca_dev->present = 1; 1878 gspca_dev->present = 1;
1884 ret = video_register_device(&gspca_dev->vdev, 1879 video_set_drvdata(gspca_dev->vdev, gspca_dev);
1880 ret = video_register_device(gspca_dev->vdev,
1885 VFL_TYPE_GRABBER, 1881 VFL_TYPE_GRABBER,
1886 video_nr); 1882 video_nr);
1887 if (ret < 0) { 1883 if (ret < 0) {
1888 err("video_register_device err %d", ret); 1884 err("video_register_device err %d", ret);
1885 video_device_release(gspca_dev->vdev);
1889 goto out; 1886 goto out;
1890 } 1887 }
1891 1888
@@ -1893,7 +1890,8 @@ int gspca_dev_probe(struct usb_interface *intf,
1893 PDEBUG(D_PROBE, "probe ok"); 1890 PDEBUG(D_PROBE, "probe ok");
1894 return 0; 1891 return 0;
1895out: 1892out:
1896 kref_put(&gspca_dev->kref, gspca_delete); 1893 kfree(gspca_dev->usb_buf);
1894 kfree(gspca_dev);
1897 return ret; 1895 return ret;
1898} 1896}
1899EXPORT_SYMBOL(gspca_dev_probe); 1897EXPORT_SYMBOL(gspca_dev_probe);
@@ -1911,7 +1909,7 @@ void gspca_disconnect(struct usb_interface *intf)
1911 usb_set_intfdata(intf, NULL); 1909 usb_set_intfdata(intf, NULL);
1912 1910
1913/* We don't want people trying to open up the device */ 1911/* We don't want people trying to open up the device */
1914 video_unregister_device(&gspca_dev->vdev); 1912 video_unregister_device(gspca_dev->vdev);
1915 1913
1916 gspca_dev->present = 0; 1914 gspca_dev->present = 0;
1917 gspca_dev->streaming = 0; 1915 gspca_dev->streaming = 0;
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 2ae1ad7c1483..d25e8d69373b 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -120,7 +120,7 @@ struct gspca_frame {
120}; 120};
121 121
122struct gspca_dev { 122struct gspca_dev {
123 struct video_device vdev; /* !! must be the first item */ 123 struct video_device *vdev;
124 struct module *module; /* subdriver handling the device */ 124 struct module *module; /* subdriver handling the device */
125 struct usb_device *dev; 125 struct usb_device *dev;
126 struct kref kref; 126 struct kref kref;