aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/saa7146_fops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/common/saa7146_fops.c')
-rw-r--r--drivers/media/common/saa7146_fops.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 0cdbd742974a..b3890bd49df6 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -201,7 +201,7 @@ static int fops_open(struct file *file)
201 201
202 DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); 202 DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev));
203 203
204 if (mutex_lock_interruptible(&saa7146_devices_lock)) 204 if (mutex_lock_interruptible(vdev->lock))
205 return -ERESTARTSYS; 205 return -ERESTARTSYS;
206 206
207 DEB_D("using: %p\n", dev); 207 DEB_D("using: %p\n", dev);
@@ -253,7 +253,7 @@ out:
253 kfree(fh); 253 kfree(fh);
254 file->private_data = NULL; 254 file->private_data = NULL;
255 } 255 }
256 mutex_unlock(&saa7146_devices_lock); 256 mutex_unlock(vdev->lock);
257 return result; 257 return result;
258} 258}
259 259
@@ -265,7 +265,7 @@ static int fops_release(struct file *file)
265 265
266 DEB_EE("file:%p\n", file); 266 DEB_EE("file:%p\n", file);
267 267
268 if (mutex_lock_interruptible(&saa7146_devices_lock)) 268 if (mutex_lock_interruptible(vdev->lock))
269 return -ERESTARTSYS; 269 return -ERESTARTSYS;
270 270
271 if (vdev->vfl_type == VFL_TYPE_VBI) { 271 if (vdev->vfl_type == VFL_TYPE_VBI) {
@@ -283,7 +283,7 @@ static int fops_release(struct file *file)
283 file->private_data = NULL; 283 file->private_data = NULL;
284 kfree(fh); 284 kfree(fh);
285 285
286 mutex_unlock(&saa7146_devices_lock); 286 mutex_unlock(vdev->lock);
287 287
288 return 0; 288 return 0;
289} 289}
@@ -293,6 +293,7 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
293 struct video_device *vdev = video_devdata(file); 293 struct video_device *vdev = video_devdata(file);
294 struct saa7146_fh *fh = file->private_data; 294 struct saa7146_fh *fh = file->private_data;
295 struct videobuf_queue *q; 295 struct videobuf_queue *q;
296 int res;
296 297
297 switch (vdev->vfl_type) { 298 switch (vdev->vfl_type) {
298 case VFL_TYPE_GRABBER: { 299 case VFL_TYPE_GRABBER: {
@@ -314,10 +315,14 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
314 return 0; 315 return 0;
315 } 316 }
316 317
317 return videobuf_mmap_mapper(q,vma); 318 if (mutex_lock_interruptible(vdev->lock))
319 return -ERESTARTSYS;
320 res = videobuf_mmap_mapper(q, vma);
321 mutex_unlock(vdev->lock);
322 return res;
318} 323}
319 324
320static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait) 325static unsigned int __fops_poll(struct file *file, struct poll_table_struct *wait)
321{ 326{
322 struct video_device *vdev = video_devdata(file); 327 struct video_device *vdev = video_devdata(file);
323 struct saa7146_fh *fh = file->private_data; 328 struct saa7146_fh *fh = file->private_data;
@@ -356,10 +361,22 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
356 return res; 361 return res;
357} 362}
358 363
364static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
365{
366 struct video_device *vdev = video_devdata(file);
367 unsigned int res;
368
369 mutex_lock(vdev->lock);
370 res = __fops_poll(file, wait);
371 mutex_unlock(vdev->lock);
372 return res;
373}
374
359static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 375static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
360{ 376{
361 struct video_device *vdev = video_devdata(file); 377 struct video_device *vdev = video_devdata(file);
362 struct saa7146_fh *fh = file->private_data; 378 struct saa7146_fh *fh = file->private_data;
379 int ret;
363 380
364 switch (vdev->vfl_type) { 381 switch (vdev->vfl_type) {
365 case VFL_TYPE_GRABBER: 382 case VFL_TYPE_GRABBER:
@@ -373,8 +390,13 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
373 DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", 390 DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n",
374 file, data, (unsigned long)count); 391 file, data, (unsigned long)count);
375*/ 392*/
376 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) 393 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) {
377 return saa7146_vbi_uops.read(file,data,count,ppos); 394 if (mutex_lock_interruptible(vdev->lock))
395 return -ERESTARTSYS;
396 ret = saa7146_vbi_uops.read(file, data, count, ppos);
397 mutex_unlock(vdev->lock);
398 return ret;
399 }
378 return -EINVAL; 400 return -EINVAL;
379 default: 401 default:
380 BUG(); 402 BUG();
@@ -386,15 +408,20 @@ static ssize_t fops_write(struct file *file, const char __user *data, size_t cou
386{ 408{
387 struct video_device *vdev = video_devdata(file); 409 struct video_device *vdev = video_devdata(file);
388 struct saa7146_fh *fh = file->private_data; 410 struct saa7146_fh *fh = file->private_data;
411 int ret;
389 412
390 switch (vdev->vfl_type) { 413 switch (vdev->vfl_type) {
391 case VFL_TYPE_GRABBER: 414 case VFL_TYPE_GRABBER:
392 return -EINVAL; 415 return -EINVAL;
393 case VFL_TYPE_VBI: 416 case VFL_TYPE_VBI:
394 if (fh->dev->ext_vv_data->vbi_fops.write) 417 if (fh->dev->ext_vv_data->vbi_fops.write) {
395 return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos); 418 if (mutex_lock_interruptible(vdev->lock))
396 else 419 return -ERESTARTSYS;
397 return -EINVAL; 420 ret = fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
421 mutex_unlock(vdev->lock);
422 return ret;
423 }
424 return -EINVAL;
398 default: 425 default:
399 BUG(); 426 BUG();
400 return -EINVAL; 427 return -EINVAL;
@@ -584,10 +611,6 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
584 else 611 else
585 vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops; 612 vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
586 vfd->release = video_device_release; 613 vfd->release = video_device_release;
587 /* Locking in file operations other than ioctl should be done by
588 the driver, not the V4L2 core.
589 This driver needs auditing so that this flag can be removed. */
590 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
591 vfd->lock = &dev->v4l2_lock; 614 vfd->lock = &dev->v4l2_lock;
592 vfd->v4l2_dev = &dev->v4l2_dev; 615 vfd->v4l2_dev = &dev->v4l2_dev;
593 vfd->tvnorms = 0; 616 vfd->tvnorms = 0;