diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 13 | ||||
-rw-r--r-- | drivers/media/video/gspca/gspca.h | 2 |
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 | ||
122 | struct gspca_dev { | 122 | struct 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 */ |