aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-10-11 09:48:11 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-21 09:36:26 -0400
commit9efd85dfff92d9b52675045362677064321332bf (patch)
treeb6d253375d1045a402f84570fae5a6b181524cd3 /drivers/staging
parent4ae18398008d9a7fdddc6beb2e0b85fcc9cf093d (diff)
[media] tm6000: fix resource locking
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/tm6000/tm6000-video.c56
-rw-r--r--drivers/staging/tm6000/tm6000.h4
2 files changed, 45 insertions, 15 deletions
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 4a5fe6670fb..cb251af895b 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -788,25 +788,49 @@ static struct videobuf_queue_ops tm6000_video_qops = {
788 IOCTL handling 788 IOCTL handling
789 ------------------------------------------------------------------*/ 789 ------------------------------------------------------------------*/
790 790
791static int res_get(struct tm6000_core *dev, struct tm6000_fh *fh) 791static bool is_res_read(struct tm6000_core *dev, struct tm6000_fh *fh)
792{ 792{
793 /* is it free? */ 793 /* Is the current fh handling it? if so, that's OK */
794 if (dev->resources) 794 if (dev->resources == fh && dev->is_res_read)
795 return 0; 795 return true;
796 /* it's free, grab it */ 796
797 dev->resources =1; 797 return false;
798 dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: get\n"); 798}
799 return 1; 799
800static bool is_res_streaming(struct tm6000_core *dev, struct tm6000_fh *fh)
801{
802 /* Is the current fh handling it? if so, that's OK */
803 if (dev->resources == fh)
804 return true;
805
806 return false;
800} 807}
801 808
802static int res_locked(struct tm6000_core *dev) 809static bool res_get(struct tm6000_core *dev, struct tm6000_fh *fh,
810 bool is_res_read)
803{ 811{
804 return (dev->resources); 812 /* Is the current fh handling it? if so, that's OK */
813 if (dev->resources == fh && dev->is_res_read == is_res_read)
814 return true;
815
816 /* is it free? */
817 if (dev->resources)
818 return false;
819
820 /* grab it */
821 dev->resources = fh;
822 dev->is_res_read = is_res_read;
823 dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: get\n");
824 return true;
805} 825}
806 826
807static void res_free(struct tm6000_core *dev, struct tm6000_fh *fh) 827static void res_free(struct tm6000_core *dev, struct tm6000_fh *fh)
808{ 828{
809 dev->resources = 0; 829 /* Is the current fh handling it? if so, that's OK */
830 if (dev->resources != fh)
831 return;
832
833 dev->resources = NULL;
810 dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: put\n"); 834 dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: put\n");
811} 835}
812 836
@@ -981,7 +1005,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
981 if (i != fh->type) 1005 if (i != fh->type)
982 return -EINVAL; 1006 return -EINVAL;
983 1007
984 if (!res_get(dev,fh)) 1008 if (!res_get(dev, fh, false))
985 return -EBUSY; 1009 return -EBUSY;
986 return (videobuf_streamon(&fh->vb_vidq)); 1010 return (videobuf_streamon(&fh->vb_vidq));
987} 1011}
@@ -1310,7 +1334,7 @@ tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos)
1310 struct tm6000_fh *fh = file->private_data; 1334 struct tm6000_fh *fh = file->private_data;
1311 1335
1312 if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1336 if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1313 if (res_locked(fh->dev)) 1337 if (!res_get(fh->dev, fh, true))
1314 return -EBUSY; 1338 return -EBUSY;
1315 1339
1316 return videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0, 1340 return videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0,
@@ -1328,7 +1352,10 @@ tm6000_poll(struct file *file, struct poll_table_struct *wait)
1328 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) 1352 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1329 return POLLERR; 1353 return POLLERR;
1330 1354
1331 if (res_get(fh->dev,fh)) { 1355 if (!!is_res_streaming(fh->dev, fh))
1356 return POLLERR;
1357
1358 if (!is_res_read(fh->dev, fh)) {
1332 /* streaming capture */ 1359 /* streaming capture */
1333 if (list_empty(&fh->vb_vidq.stream)) 1360 if (list_empty(&fh->vb_vidq.stream))
1334 return POLLERR; 1361 return POLLERR;
@@ -1356,6 +1383,7 @@ static int tm6000_release(struct file *file)
1356 1383
1357 dev->users--; 1384 dev->users--;
1358 1385
1386 res_free(dev, fh);
1359 if (!dev->users) { 1387 if (!dev->users) {
1360 tm6000_uninit_isoc(dev); 1388 tm6000_uninit_isoc(dev);
1361 videobuf_mmap_free(&fh->vb_vidq); 1389 videobuf_mmap_free(&fh->vb_vidq);
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index 5d9dcab5c87..a1c6ca2647e 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -189,7 +189,9 @@ struct tm6000_core {
189 int users; 189 int users;
190 190
191 /* various device info */ 191 /* various device info */
192 unsigned int resources; 192 struct tm6000_fh *resources; /* Points to fh that is streaming */
193 bool is_res_read;
194
193 struct video_device *vfd; 195 struct video_device *vfd;
194 struct tm6000_dmaqueue vidq; 196 struct tm6000_dmaqueue vidq;
195 struct v4l2_device v4l2_dev; 197 struct v4l2_device v4l2_dev;