aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-11-18 13:52:31 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-11-24 09:01:23 -0500
commit5c4fa002b1c7b40f65fa911ae17a823ec9e26ab2 (patch)
treede334f5d2dcdb93fff14584957ed820f9fe57208 /drivers
parent98522a7be97f2b23451342e36c39f412f0461e24 (diff)
V4L/DVB (9690): gspca: Lock the subdrivers via module_get/put.
The previous subdriver protection against rmmod was done via the file operations table in the device descriptor. On device disconnection while streaming, the device structure was freed at close time, and the module_put still used the module name in the freed area. Now, explicit module get/put are done on open and close. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/gspca.c13
-rw-r--r--drivers/media/video/gspca/gspca.h2
2 files changed, 11 insertions, 4 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index f28d2f4aceac..a565f3764837 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -874,6 +874,13 @@ static int dev_open(struct inode *inode, struct file *file)
874 ret = -EBUSY; 874 ret = -EBUSY;
875 goto out; 875 goto out;
876 } 876 }
877
878 /* protect the subdriver against rmmod */
879 if (!try_module_get(gspca_dev->module)) {
880 ret = -ENODEV;
881 goto out;
882 }
883
877 gspca_dev->users++; 884 gspca_dev->users++;
878 885
879 /* one more user */ 886 /* one more user */
@@ -920,6 +927,7 @@ static int dev_close(struct inode *inode, struct file *file)
920 gspca_dev->memory = GSPCA_MEMORY_NO; 927 gspca_dev->memory = GSPCA_MEMORY_NO;
921 } 928 }
922 file->private_data = NULL; 929 file->private_data = NULL;
930 module_put(gspca_dev->module);
923 mutex_unlock(&gspca_dev->queue_lock); 931 mutex_unlock(&gspca_dev->queue_lock);
924 932
925 PDEBUG(D_STREAM, "close done"); 933 PDEBUG(D_STREAM, "close done");
@@ -1870,9 +1878,8 @@ int gspca_dev_probe(struct usb_interface *intf,
1870 /* init video stuff */ 1878 /* init video stuff */
1871 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); 1879 memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
1872 gspca_dev->vdev.parent = &dev->dev; 1880 gspca_dev->vdev.parent = &dev->dev;
1873 memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops); 1881 gspca_dev->vdev.fops = &dev_fops;
1874 gspca_dev->vdev.fops = &gspca_dev->fops; 1882 gspca_dev->module = module;
1875 gspca_dev->fops.owner = module; /* module protection */
1876 gspca_dev->present = 1; 1883 gspca_dev->present = 1;
1877 ret = video_register_device(&gspca_dev->vdev, 1884 ret = video_register_device(&gspca_dev->vdev,
1878 VFL_TYPE_GRABBER, 1885 VFL_TYPE_GRABBER,
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index c35d7b97112f..2ae1ad7c1483 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -121,7 +121,7 @@ struct gspca_frame {
121 121
122struct gspca_dev { 122struct gspca_dev {
123 struct video_device vdev; /* !! must be the first item */ 123 struct video_device vdev; /* !! must be the first item */
124 struct file_operations fops; 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;
127 struct file *capt_file; /* file doing video capture */ 127 struct file *capt_file; /* file doing video capture */