diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-07-16 11:52:41 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-05 11:00:26 -0300 |
commit | 60c66b6f276ec2a1f76788f0833ad2bf366522b6 (patch) | |
tree | b93f8f22566268cd124feeacd5f099015ee9e210 /drivers/media/usb/tlg2300/pd-video.c | |
parent | d4de6e406211028b9186e223b766bcd17579ec97 (diff) | |
download | blackbird-op-linux-60c66b6f276ec2a1f76788f0833ad2bf366522b6.tar.gz blackbird-op-linux-60c66b6f276ec2a1f76788f0833ad2bf366522b6.zip |
[media] tlg2300: allow multiple opens
Due to a poor administration of the driver state it wasn't possible to open
a video or vbi device multiple times.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Huang Shijie <shijie8@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/tlg2300/pd-video.c')
-rw-r--r-- | drivers/media/usb/tlg2300/pd-video.c | 40 |
1 files changed, 15 insertions, 25 deletions
diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c index 4c045b3c1456..834428d90766 100644 --- a/drivers/media/usb/tlg2300/pd-video.c +++ b/drivers/media/usb/tlg2300/pd-video.c @@ -1352,12 +1352,14 @@ static int pd_video_open(struct file *file) mutex_lock(&pd->lock); usb_autopm_get_interface(pd->interface); - if (vfd->vfl_type == VFL_TYPE_GRABBER - && !(pd->state & POSEIDON_STATE_ANALOG)) { - front = kzalloc(sizeof(struct front_face), GFP_KERNEL); - if (!front) - goto out; - + if (pd->state && !(pd->state & POSEIDON_STATE_ANALOG)) { + ret = -EBUSY; + goto out; + } + front = kzalloc(sizeof(struct front_face), GFP_KERNEL); + if (!front) + goto out; + if (vfd->vfl_type == VFL_TYPE_GRABBER) { pd->cur_transfer_mode = usb_transfer_mode;/* bulk or iso */ init_video_context(&pd->video_data.context); @@ -1368,7 +1370,6 @@ static int pd_video_open(struct file *file) goto out; } - pd->state |= POSEIDON_STATE_ANALOG; front->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; pd->video_data.users++; set_debug_mode(vfd, debug_mode); @@ -1379,13 +1380,7 @@ static int pd_video_open(struct file *file) V4L2_FIELD_INTERLACED,/* video is interlacd */ sizeof(struct videobuf_buffer),/*it's enough*/ front, NULL); - } else if (vfd->vfl_type == VFL_TYPE_VBI - && !(pd->state & POSEIDON_STATE_VBI)) { - front = kzalloc(sizeof(struct front_face), GFP_KERNEL); - if (!front) - goto out; - - pd->state |= POSEIDON_STATE_VBI; + } else { front->type = V4L2_BUF_TYPE_VBI_CAPTURE; pd->vbi_data.front = front; pd->vbi_data.users++; @@ -1396,19 +1391,15 @@ static int pd_video_open(struct file *file) V4L2_FIELD_NONE, /* vbi is NONE mode */ sizeof(struct videobuf_buffer), front, NULL); - } else { - /* maybe add FM support here */ - log("other "); - ret = -EINVAL; - goto out; } - front->pd = pd; - front->curr_frame = NULL; + pd->state |= POSEIDON_STATE_ANALOG; + front->pd = pd; + front->curr_frame = NULL; INIT_LIST_HEAD(&front->active); spin_lock_init(&front->queue_lock); - file->private_data = front; + file->private_data = front; kref_get(&pd->kref); mutex_unlock(&pd->lock); @@ -1429,8 +1420,6 @@ static int pd_video_release(struct file *file) mutex_lock(&pd->lock); if (front->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - pd->state &= ~POSEIDON_STATE_ANALOG; - /* stop the device, and free the URBs */ usb_transfer_stop(&pd->video_data); free_all_urb(&pd->video_data); @@ -1442,10 +1431,11 @@ static int pd_video_release(struct file *file) pd->file_for_stream = NULL; pd->video_data.users--; } else if (front->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - pd->state &= ~POSEIDON_STATE_VBI; pd->vbi_data.front = NULL; pd->vbi_data.users--; } + if (!pd->vbi_data.users && !pd->video_data.users) + pd->state &= ~POSEIDON_STATE_ANALOG; videobuf_stop(&front->q); videobuf_mmap_free(&front->q); |