aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-04-06 05:00:17 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-14 18:57:32 -0400
commitede197aac0c64021a0b2139d19edd8fa066530c2 (patch)
tree2865f3550473c1fe42c4bb462de21e575166fc7d /drivers/media
parent99c77aa4281c41fab255a4eb25ccc36a8c2e113d (diff)
[media] hdpvr: remove hdpvr_fh and just use v4l2_fh
This prepares the driver for priority and control event handling. This patch also checks for correct streaming ownership and it makes a small improvement to the encoder_cmd ioctls: always zero 'flags' and drop the memset of 'raw' as that is already done by the v4l2 core. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-video.c115
-rw-r--r--drivers/media/usb/hdpvr/hdpvr.h4
2 files changed, 46 insertions, 73 deletions
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
index a89012720e5a..4bbcf480d5e7 100644
--- a/drivers/media/usb/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -35,10 +35,6 @@
35 list_size(&dev->free_buff_list), \ 35 list_size(&dev->free_buff_list), \
36 list_size(&dev->rec_buff_list)); } 36 list_size(&dev->rec_buff_list)); }
37 37
38struct hdpvr_fh {
39 struct hdpvr_device *dev;
40};
41
42static uint list_size(struct list_head *list) 38static uint list_size(struct list_head *list)
43{ 39{
44 struct list_head *tmp; 40 struct list_head *tmp;
@@ -358,55 +354,21 @@ static int hdpvr_stop_streaming(struct hdpvr_device *dev)
358 * video 4 linux 2 file operations 354 * video 4 linux 2 file operations
359 */ 355 */
360 356
361static int hdpvr_open(struct file *file)
362{
363 struct hdpvr_device *dev;
364 struct hdpvr_fh *fh;
365 int retval = -ENOMEM;
366
367 dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
368 if (!dev) {
369 pr_err("open failing with with ENODEV\n");
370 retval = -ENODEV;
371 goto err;
372 }
373
374 fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
375 if (!fh) {
376 v4l2_err(&dev->v4l2_dev, "Out of memory\n");
377 goto err;
378 }
379 /* lock the device to allow correctly handling errors
380 * in resumption */
381 mutex_lock(&dev->io_mutex);
382 dev->open_count++;
383 mutex_unlock(&dev->io_mutex);
384
385 fh->dev = dev;
386
387 /* save our object in the file's private structure */
388 file->private_data = fh;
389
390 retval = 0;
391err:
392 return retval;
393}
394
395static int hdpvr_release(struct file *file) 357static int hdpvr_release(struct file *file)
396{ 358{
397 struct hdpvr_fh *fh = file->private_data; 359 struct hdpvr_device *dev = video_drvdata(file);
398 struct hdpvr_device *dev = fh->dev;
399 360
400 if (!dev) 361 if (!dev)
401 return -ENODEV; 362 return -ENODEV;
402 363
403 mutex_lock(&dev->io_mutex); 364 mutex_lock(&dev->io_mutex);
404 if (!(--dev->open_count) && dev->status == STATUS_STREAMING) 365 if (file->private_data == dev->owner) {
405 hdpvr_stop_streaming(dev); 366 hdpvr_stop_streaming(dev);
406 367 dev->owner = NULL;
368 }
407 mutex_unlock(&dev->io_mutex); 369 mutex_unlock(&dev->io_mutex);
408 370
409 return 0; 371 return v4l2_fh_release(file);
410} 372}
411 373
412/* 374/*
@@ -416,8 +378,7 @@ static int hdpvr_release(struct file *file)
416static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, 378static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
417 loff_t *pos) 379 loff_t *pos)
418{ 380{
419 struct hdpvr_fh *fh = file->private_data; 381 struct hdpvr_device *dev = video_drvdata(file);
420 struct hdpvr_device *dev = fh->dev;
421 struct hdpvr_buffer *buf = NULL; 382 struct hdpvr_buffer *buf = NULL;
422 struct urb *urb; 383 struct urb *urb;
423 unsigned int ret = 0; 384 unsigned int ret = 0;
@@ -440,6 +401,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
440 mutex_unlock(&dev->io_mutex); 401 mutex_unlock(&dev->io_mutex);
441 goto err; 402 goto err;
442 } 403 }
404 dev->owner = file->private_data;
443 print_buffer_status(); 405 print_buffer_status();
444 } 406 }
445 mutex_unlock(&dev->io_mutex); 407 mutex_unlock(&dev->io_mutex);
@@ -518,8 +480,7 @@ err:
518static unsigned int hdpvr_poll(struct file *filp, poll_table *wait) 480static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
519{ 481{
520 struct hdpvr_buffer *buf = NULL; 482 struct hdpvr_buffer *buf = NULL;
521 struct hdpvr_fh *fh = filp->private_data; 483 struct hdpvr_device *dev = video_drvdata(filp);
522 struct hdpvr_device *dev = fh->dev;
523 unsigned int mask = 0; 484 unsigned int mask = 0;
524 485
525 mutex_lock(&dev->io_mutex); 486 mutex_lock(&dev->io_mutex);
@@ -534,6 +495,8 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
534 v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, 495 v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
535 "start_streaming failed\n"); 496 "start_streaming failed\n");
536 dev->status = STATUS_IDLE; 497 dev->status = STATUS_IDLE;
498 } else {
499 dev->owner = filp->private_data;
537 } 500 }
538 501
539 print_buffer_status(); 502 print_buffer_status();
@@ -555,7 +518,7 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
555 518
556static const struct v4l2_file_operations hdpvr_fops = { 519static const struct v4l2_file_operations hdpvr_fops = {
557 .owner = THIS_MODULE, 520 .owner = THIS_MODULE,
558 .open = hdpvr_open, 521 .open = v4l2_fh_open,
559 .release = hdpvr_release, 522 .release = hdpvr_release,
560 .read = hdpvr_read, 523 .read = hdpvr_read,
561 .poll = hdpvr_poll, 524 .poll = hdpvr_poll,
@@ -584,8 +547,7 @@ static int vidioc_querycap(struct file *file, void *priv,
584static int vidioc_s_std(struct file *file, void *private_data, 547static int vidioc_s_std(struct file *file, void *private_data,
585 v4l2_std_id std) 548 v4l2_std_id std)
586{ 549{
587 struct hdpvr_fh *fh = file->private_data; 550 struct hdpvr_device *dev = video_drvdata(file);
588 struct hdpvr_device *dev = fh->dev;
589 u8 std_type = 1; 551 u8 std_type = 1;
590 552
591 if (std & (V4L2_STD_NTSC | V4L2_STD_PAL_60)) 553 if (std & (V4L2_STD_NTSC | V4L2_STD_PAL_60))
@@ -603,8 +565,7 @@ static const char *iname[] = {
603static int vidioc_enum_input(struct file *file, void *priv, 565static int vidioc_enum_input(struct file *file, void *priv,
604 struct v4l2_input *i) 566 struct v4l2_input *i)
605{ 567{
606 struct hdpvr_fh *fh = file->private_data; 568 struct hdpvr_device *dev = video_drvdata(file);
607 struct hdpvr_device *dev = fh->dev;
608 unsigned int n; 569 unsigned int n;
609 570
610 n = i->index; 571 n = i->index;
@@ -626,8 +587,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
626static int vidioc_s_input(struct file *file, void *private_data, 587static int vidioc_s_input(struct file *file, void *private_data,
627 unsigned int index) 588 unsigned int index)
628{ 589{
629 struct hdpvr_fh *fh = file->private_data; 590 struct hdpvr_device *dev = video_drvdata(file);
630 struct hdpvr_device *dev = fh->dev;
631 int retval; 591 int retval;
632 592
633 if (index >= HDPVR_VIDEO_INPUTS) 593 if (index >= HDPVR_VIDEO_INPUTS)
@@ -646,8 +606,7 @@ static int vidioc_s_input(struct file *file, void *private_data,
646static int vidioc_g_input(struct file *file, void *private_data, 606static int vidioc_g_input(struct file *file, void *private_data,
647 unsigned int *index) 607 unsigned int *index)
648{ 608{
649 struct hdpvr_fh *fh = file->private_data; 609 struct hdpvr_device *dev = video_drvdata(file);
650 struct hdpvr_device *dev = fh->dev;
651 610
652 *index = dev->options.video_input; 611 *index = dev->options.video_input;
653 return 0; 612 return 0;
@@ -680,8 +639,7 @@ static int vidioc_enumaudio(struct file *file, void *priv,
680static int vidioc_s_audio(struct file *file, void *private_data, 639static int vidioc_s_audio(struct file *file, void *private_data,
681 const struct v4l2_audio *audio) 640 const struct v4l2_audio *audio)
682{ 641{
683 struct hdpvr_fh *fh = file->private_data; 642 struct hdpvr_device *dev = video_drvdata(file);
684 struct hdpvr_device *dev = fh->dev;
685 int retval; 643 int retval;
686 644
687 if (audio->index >= HDPVR_AUDIO_INPUTS) 645 if (audio->index >= HDPVR_AUDIO_INPUTS)
@@ -700,8 +658,7 @@ static int vidioc_s_audio(struct file *file, void *private_data,
700static int vidioc_g_audio(struct file *file, void *private_data, 658static int vidioc_g_audio(struct file *file, void *private_data,
701 struct v4l2_audio *audio) 659 struct v4l2_audio *audio)
702{ 660{
703 struct hdpvr_fh *fh = file->private_data; 661 struct hdpvr_device *dev = video_drvdata(file);
704 struct hdpvr_device *dev = fh->dev;
705 662
706 audio->index = dev->options.audio_input; 663 audio->index = dev->options.audio_input;
707 audio->capability = V4L2_AUDCAP_STEREO; 664 audio->capability = V4L2_AUDCAP_STEREO;
@@ -833,8 +790,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
833static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data, 790static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data,
834 struct v4l2_format *f) 791 struct v4l2_format *f)
835{ 792{
836 struct hdpvr_fh *fh = file->private_data; 793 struct hdpvr_device *dev = video_drvdata(file);
837 struct hdpvr_device *dev = fh->dev;
838 struct hdpvr_video_info *vid_info; 794 struct hdpvr_video_info *vid_info;
839 795
840 if (!dev) 796 if (!dev)
@@ -860,26 +816,44 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data,
860static int vidioc_encoder_cmd(struct file *filp, void *priv, 816static int vidioc_encoder_cmd(struct file *filp, void *priv,
861 struct v4l2_encoder_cmd *a) 817 struct v4l2_encoder_cmd *a)
862{ 818{
863 struct hdpvr_fh *fh = filp->private_data; 819 struct hdpvr_device *dev = video_drvdata(filp);
864 struct hdpvr_device *dev = fh->dev; 820 int res = 0;
865 int res;
866 821
867 mutex_lock(&dev->io_mutex); 822 mutex_lock(&dev->io_mutex);
823 a->flags = 0;
868 824
869 memset(&a->raw, 0, sizeof(a->raw));
870 switch (a->cmd) { 825 switch (a->cmd) {
871 case V4L2_ENC_CMD_START: 826 case V4L2_ENC_CMD_START:
872 a->flags = 0; 827 if (dev->owner && filp->private_data != dev->owner) {
828 res = -EBUSY;
829 break;
830 }
831 if (dev->status == STATUS_STREAMING)
832 break;
873 res = hdpvr_start_streaming(dev); 833 res = hdpvr_start_streaming(dev);
834 if (!res)
835 dev->owner = filp->private_data;
836 else
837 dev->status = STATUS_IDLE;
874 break; 838 break;
875 case V4L2_ENC_CMD_STOP: 839 case V4L2_ENC_CMD_STOP:
840 if (dev->owner && filp->private_data != dev->owner) {
841 res = -EBUSY;
842 break;
843 }
844 if (dev->status == STATUS_IDLE)
845 break;
876 res = hdpvr_stop_streaming(dev); 846 res = hdpvr_stop_streaming(dev);
847 if (!res)
848 dev->owner = NULL;
877 break; 849 break;
878 default: 850 default:
879 v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, 851 v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
880 "Unsupported encoder cmd %d\n", a->cmd); 852 "Unsupported encoder cmd %d\n", a->cmd);
881 res = -EINVAL; 853 res = -EINVAL;
854 break;
882 } 855 }
856
883 mutex_unlock(&dev->io_mutex); 857 mutex_unlock(&dev->io_mutex);
884 return res; 858 return res;
885} 859}
@@ -887,6 +861,7 @@ static int vidioc_encoder_cmd(struct file *filp, void *priv,
887static int vidioc_try_encoder_cmd(struct file *filp, void *priv, 861static int vidioc_try_encoder_cmd(struct file *filp, void *priv,
888 struct v4l2_encoder_cmd *a) 862 struct v4l2_encoder_cmd *a)
889{ 863{
864 a->flags = 0;
890 switch (a->cmd) { 865 switch (a->cmd) {
891 case V4L2_ENC_CMD_START: 866 case V4L2_ENC_CMD_START:
892 case V4L2_ENC_CMD_STOP: 867 case V4L2_ENC_CMD_STOP:
@@ -935,8 +910,6 @@ static void hdpvr_device_release(struct video_device *vdev)
935} 910}
936 911
937static const struct video_device hdpvr_video_template = { 912static const struct video_device hdpvr_video_template = {
938/* .type = VFL_TYPE_GRABBER, */
939/* .type2 = VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */
940 .fops = &hdpvr_fops, 913 .fops = &hdpvr_fops,
941 .release = hdpvr_device_release, 914 .release = hdpvr_device_release,
942 .ioctl_ops = &hdpvr_ioctl_ops, 915 .ioctl_ops = &hdpvr_ioctl_ops,
@@ -1031,9 +1004,9 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
1031 goto error; 1004 goto error;
1032 } 1005 }
1033 1006
1034 *(dev->video_dev) = hdpvr_video_template; 1007 *dev->video_dev = hdpvr_video_template;
1035 strcpy(dev->video_dev->name, "Hauppauge HD PVR"); 1008 strcpy(dev->video_dev->name, "Hauppauge HD PVR");
1036 dev->video_dev->parent = parent; 1009 dev->video_dev->v4l2_dev = &dev->v4l2_dev;
1037 video_set_drvdata(dev->video_dev, dev); 1010 video_set_drvdata(dev->video_dev, dev);
1038 1011
1039 res = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum); 1012 res = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum);
diff --git a/drivers/media/usb/hdpvr/hdpvr.h b/drivers/media/usb/hdpvr/hdpvr.h
index 2a4deab70762..945009356127 100644
--- a/drivers/media/usb/hdpvr/hdpvr.h
+++ b/drivers/media/usb/hdpvr/hdpvr.h
@@ -85,8 +85,6 @@ struct hdpvr_device {
85 85
86 /* holds the current device status */ 86 /* holds the current device status */
87 __u8 status; 87 __u8 status;
88 /* count the number of openers */
89 uint open_count;
90 88
91 /* holds the cureent set options */ 89 /* holds the cureent set options */
92 struct hdpvr_options options; 90 struct hdpvr_options options;
@@ -107,6 +105,8 @@ struct hdpvr_device {
107 struct workqueue_struct *workqueue; 105 struct workqueue_struct *workqueue;
108 /**/ 106 /**/
109 struct work_struct worker; 107 struct work_struct worker;
108 /* current stream owner */
109 struct v4l2_fh *owner;
110 110
111 /* I2C adapter */ 111 /* I2C adapter */
112 struct i2c_adapter i2c_adapter; 112 struct i2c_adapter i2c_adapter;