From: Hans Verkuil Date: Mon, 16 Jul 2012 14:52:41 +0000 (-0300) Subject: [media] tlg2300: allow multiple opens X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=60c66b6f276ec2a1f76788f0833ad2bf366522b6;p=linux-beck.git [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 Acked-by: Huang Shijie Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h index cb5cb0f70062..3010496787ab 100644 --- a/drivers/media/usb/tlg2300/pd-common.h +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -26,7 +26,6 @@ #define POSEIDON_STATE_ANALOG (0x0001) #define POSEIDON_STATE_FM (0x0002) #define POSEIDON_STATE_DVBT (0x0004) -#define POSEIDON_STATE_VBI (0x0008) #define POSEIDON_STATE_DISCONNECT (0x0080) #define PM_SUSPEND_DELAY 3 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);