diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-11-19 04:37:53 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-24 09:01:38 -0500 |
commit | e07a1d8ab20a059fefbfd1558db43701bca560d7 (patch) | |
tree | 834a4dc09da2e86ecbab2ce7ae4a5e2b298ebfd6 /drivers/media/video/gspca/gspca.c | |
parent | 5c4fa002b1c7b40f65fa911ae17a823ec9e26ab2 (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>
Diffstat (limited to 'drivers/media/video/gspca/gspca.c')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 28 |
1 files changed, 13 insertions, 15 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 | ||
1758 | static void dev_release(struct video_device *vfd) | ||
1759 | { | ||
1760 | /* nothing */ | ||
1761 | } | ||
1762 | |||
1763 | static struct file_operations dev_fops = { | 1758 | static 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; |
1895 | out: | 1892 | out: |
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 | } |
1899 | EXPORT_SYMBOL(gspca_dev_probe); | 1897 | EXPORT_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; |