aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrandon Philips <brandon@ifup.org>2008-04-02 17:10:59 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:07:57 -0400
commitaa9dbac426d263b5b86d1684993d18ae187d7588 (patch)
tree942a7399e4ea9e2c135d71008461dbd5c3cd11bf
parentcbcb565f74cf01d680f83af531490bb2c5375af0 (diff)
V4L/DVB (7491): vivi: make vivi openable only once
vivi currently doesn't have the infrastructure to handle being opened more than one time and will crash if it is. So, make it openable only once. Signed-off-by: Brandon Philips <bphilips@suse.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/vivi.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 0e623179f8a..02a232768e3 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
1047found: 1049found:
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 }
1069unlock:
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;