aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2010-11-26 04:43:51 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-01 17:10:18 -0500
commit2877842de8cbf6272b0a851cb12587b7dd8c2afb (patch)
tree1f04f8d9a4873a5904e5a2f0278f3423cef0d2ca /drivers
parent78b055be2710b63cb196fc37669f3b662fecc9e4 (diff)
[media] v4l2-dev: use mutex_lock_interruptible instead of plain mutex_lock
Where reasonable use mutex_lock_interruptible instead of mutex_lock. Also fix the poll, read and write error codes when called with an unregistered device (e.g. after a USB device was disconnected). Poll must return POLLERR|POLLHUP and read/write must return -ENODEV. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/v4l2-dev.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 03f7f4670e9b..bfd392e2436d 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -186,12 +186,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf,
186 size_t sz, loff_t *off) 186 size_t sz, loff_t *off)
187{ 187{
188 struct video_device *vdev = video_devdata(filp); 188 struct video_device *vdev = video_devdata(filp);
189 int ret = -EIO; 189 int ret = -ENODEV;
190 190
191 if (!vdev->fops->read) 191 if (!vdev->fops->read)
192 return -EINVAL; 192 return -EINVAL;
193 if (vdev->lock) 193 if (vdev->lock && mutex_lock_interruptible(vdev->lock))
194 mutex_lock(vdev->lock); 194 return -ERESTARTSYS;
195 if (video_is_registered(vdev)) 195 if (video_is_registered(vdev))
196 ret = vdev->fops->read(filp, buf, sz, off); 196 ret = vdev->fops->read(filp, buf, sz, off);
197 if (vdev->lock) 197 if (vdev->lock)
@@ -203,12 +203,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
203 size_t sz, loff_t *off) 203 size_t sz, loff_t *off)
204{ 204{
205 struct video_device *vdev = video_devdata(filp); 205 struct video_device *vdev = video_devdata(filp);
206 int ret = -EIO; 206 int ret = -ENODEV;
207 207
208 if (!vdev->fops->write) 208 if (!vdev->fops->write)
209 return -EINVAL; 209 return -EINVAL;
210 if (vdev->lock) 210 if (vdev->lock && mutex_lock_interruptible(vdev->lock))
211 mutex_lock(vdev->lock); 211 return -ERESTARTSYS;
212 if (video_is_registered(vdev)) 212 if (video_is_registered(vdev))
213 ret = vdev->fops->write(filp, buf, sz, off); 213 ret = vdev->fops->write(filp, buf, sz, off);
214 if (vdev->lock) 214 if (vdev->lock)
@@ -219,10 +219,10 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
219static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) 219static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
220{ 220{
221 struct video_device *vdev = video_devdata(filp); 221 struct video_device *vdev = video_devdata(filp);
222 int ret = DEFAULT_POLLMASK; 222 int ret = POLLERR | POLLHUP;
223 223
224 if (!vdev->fops->poll) 224 if (!vdev->fops->poll)
225 return ret; 225 return DEFAULT_POLLMASK;
226 if (vdev->lock) 226 if (vdev->lock)
227 mutex_lock(vdev->lock); 227 mutex_lock(vdev->lock);
228 if (video_is_registered(vdev)) 228 if (video_is_registered(vdev))
@@ -238,8 +238,8 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
238 int ret = -ENODEV; 238 int ret = -ENODEV;
239 239
240 if (vdev->fops->unlocked_ioctl) { 240 if (vdev->fops->unlocked_ioctl) {
241 if (vdev->lock) 241 if (vdev->lock && mutex_lock_interruptible(vdev->lock))
242 mutex_lock(vdev->lock); 242 return -ERESTARTSYS;
243 if (video_is_registered(vdev)) 243 if (video_is_registered(vdev))
244 ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); 244 ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
245 if (vdev->lock) 245 if (vdev->lock)
@@ -265,8 +265,8 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
265 265
266 if (!vdev->fops->mmap) 266 if (!vdev->fops->mmap)
267 return ret; 267 return ret;
268 if (vdev->lock) 268 if (vdev->lock && mutex_lock_interruptible(vdev->lock))
269 mutex_lock(vdev->lock); 269 return -ERESTARTSYS;
270 if (video_is_registered(vdev)) 270 if (video_is_registered(vdev))
271 ret = vdev->fops->mmap(filp, vm); 271 ret = vdev->fops->mmap(filp, vm);
272 if (vdev->lock) 272 if (vdev->lock)
@@ -292,8 +292,10 @@ static int v4l2_open(struct inode *inode, struct file *filp)
292 video_get(vdev); 292 video_get(vdev);
293 mutex_unlock(&videodev_lock); 293 mutex_unlock(&videodev_lock);
294 if (vdev->fops->open) { 294 if (vdev->fops->open) {
295 if (vdev->lock) 295 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
296 mutex_lock(vdev->lock); 296 ret = -ERESTARTSYS;
297 goto err;
298 }
297 if (video_is_registered(vdev)) 299 if (video_is_registered(vdev))
298 ret = vdev->fops->open(filp); 300 ret = vdev->fops->open(filp);
299 else 301 else
@@ -302,6 +304,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
302 mutex_unlock(vdev->lock); 304 mutex_unlock(vdev->lock);
303 } 305 }
304 306
307err:
305 /* decrease the refcount in case of an error */ 308 /* decrease the refcount in case of an error */
306 if (ret) 309 if (ret)
307 video_put(vdev); 310 video_put(vdev);