diff options
-rw-r--r-- | drivers/media/video/vivi.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 0e623179f8a5..02a232768e3b 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -164,6 +164,7 @@ struct vivi_dev { | |||
164 | 164 | ||
165 | struct mutex lock; | 165 | struct mutex lock; |
166 | spinlock_t slock; | 166 | spinlock_t slock; |
167 | struct mutex mutex; | ||
167 | 168 | ||
168 | int users; | 169 | int users; |
169 | 170 | ||
@@ -1036,6 +1037,7 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1036 | struct vivi_dev *dev; | 1037 | struct vivi_dev *dev; |
1037 | struct vivi_fh *fh; | 1038 | struct vivi_fh *fh; |
1038 | int i; | 1039 | int i; |
1040 | int retval = 0; | ||
1039 | 1041 | ||
1040 | printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); | 1042 | printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); |
1041 | 1043 | ||
@@ -1045,9 +1047,15 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1045 | return -ENODEV; | 1047 | return -ENODEV; |
1046 | 1048 | ||
1047 | found: | 1049 | found: |
1048 | /* If more than one user, mutex should be added */ | 1050 | mutex_lock(&dev->mutex); |
1049 | dev->users++; | 1051 | dev->users++; |
1050 | 1052 | ||
1053 | if (dev->users > 1) { | ||
1054 | dev->users--; | ||
1055 | retval = -EBUSY; | ||
1056 | goto unlock; | ||
1057 | } | ||
1058 | |||
1051 | dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, | 1059 | dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, |
1052 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); | 1060 | v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); |
1053 | 1061 | ||
@@ -1055,8 +1063,13 @@ found: | |||
1055 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 1063 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); |
1056 | if (NULL == fh) { | 1064 | if (NULL == fh) { |
1057 | dev->users--; | 1065 | dev->users--; |
1058 | return -ENOMEM; | 1066 | retval = -ENOMEM; |
1067 | goto unlock; | ||
1059 | } | 1068 | } |
1069 | unlock: | ||
1070 | mutex_unlock(&dev->mutex); | ||
1071 | if (retval) | ||
1072 | return retval; | ||
1060 | 1073 | ||
1061 | file->private_data = fh; | 1074 | file->private_data = fh; |
1062 | fh->dev = dev; | 1075 | fh->dev = dev; |
@@ -1128,7 +1141,9 @@ static int vivi_close(struct inode *inode, struct file *file) | |||
1128 | 1141 | ||
1129 | kfree(fh); | 1142 | kfree(fh); |
1130 | 1143 | ||
1144 | mutex_lock(&dev->mutex); | ||
1131 | dev->users--; | 1145 | dev->users--; |
1146 | mutex_unlock(&dev->mutex); | ||
1132 | 1147 | ||
1133 | dprintk(dev, 1, "close called (minor=%d, users=%d)\n", | 1148 | dprintk(dev, 1, "close called (minor=%d, users=%d)\n", |
1134 | minor, dev->users); | 1149 | minor, dev->users); |
@@ -1243,6 +1258,7 @@ static int __init vivi_init(void) | |||
1243 | /* initialize locks */ | 1258 | /* initialize locks */ |
1244 | mutex_init(&dev->lock); | 1259 | mutex_init(&dev->lock); |
1245 | spin_lock_init(&dev->slock); | 1260 | spin_lock_init(&dev->slock); |
1261 | mutex_init(&dev->mutex); | ||
1246 | 1262 | ||
1247 | dev->vidq.timeout.function = vivi_vid_timeout; | 1263 | dev->vidq.timeout.function = vivi_vid_timeout; |
1248 | dev->vidq.timeout.data = (unsigned long)dev; | 1264 | dev->vidq.timeout.data = (unsigned long)dev; |