|
@@ -874,6 +874,13 @@ static int dev_open(struct inode *inode, struct file *file)
|
|
|
ret = -EBUSY;
|
|
|
goto out;
|
|
|
}
|
|
|
+
|
|
|
+ /* protect the subdriver against rmmod */
|
|
|
+ if (!try_module_get(gspca_dev->module)) {
|
|
|
+ ret = -ENODEV;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
gspca_dev->users++;
|
|
|
|
|
|
/* one more user */
|
|
@@ -920,6 +927,7 @@ static int dev_close(struct inode *inode, struct file *file)
|
|
|
gspca_dev->memory = GSPCA_MEMORY_NO;
|
|
|
}
|
|
|
file->private_data = NULL;
|
|
|
+ module_put(gspca_dev->module);
|
|
|
mutex_unlock(&gspca_dev->queue_lock);
|
|
|
|
|
|
PDEBUG(D_STREAM, "close done");
|
|
@@ -1870,9 +1878,8 @@ int gspca_dev_probe(struct usb_interface *intf,
|
|
|
/* init video stuff */
|
|
|
memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
|
|
|
gspca_dev->vdev.parent = &dev->dev;
|
|
|
- memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops);
|
|
|
- gspca_dev->vdev.fops = &gspca_dev->fops;
|
|
|
- gspca_dev->fops.owner = module; /* module protection */
|
|
|
+ gspca_dev->vdev.fops = &dev_fops;
|
|
|
+ gspca_dev->module = module;
|
|
|
gspca_dev->present = 1;
|
|
|
ret = video_register_device(&gspca_dev->vdev,
|
|
|
VFL_TYPE_GRABBER,
|