aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */