mirror of
https://github.com/LineageOS/android_kernel_fxtec_sm6115.git
synced 2026-04-03 06:33:18 +00:00
media: pci: ivtv: Don't create fake v4l2_fh
[ Upstream commit cc6e8d1ccea792d8550428e0831e3a35b0ccfddc ] The ivtv driver has a structure named ivtv_open_id that models an open file handle for the device. It embeds a v4l2_fh instance for file handles that correspond to a V4L2 video device, and stores a pointer to that v4l2_fh in struct ivtv_stream to identify which open file handle owns a particular stream. In addition to video devices, streams can be owned by ALSA PCM devices. Those devices do not make use of the v4l2_fh instance for obvious reasons, but the snd_ivtv_pcm_capture_open() function still initializes a "fake" v4l2_fh for the sole purpose of using it as an open file handle identifier. The v4l2_fh is not properly destroyed when the ALSA PCM device is closed, leading to possible resource leaks. Fortunately, the v4l2_fh instance pointed to by ivtv_stream is not accessed, only the pointer value is used for comparison. Replace it with a pointer to the ivtv_open_id structure that embeds the v4l2_fh, and don't initialize the v4l2_fh for ALSA PCM devices. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Ulrich Hecht <uli@kernel.org>
This commit is contained in:
committed by
Ulrich Hecht
parent
5a6f7d4df2
commit
3b38f1f3f7
@ -159,14 +159,12 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream)
|
||||
|
||||
s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
|
||||
|
||||
v4l2_fh_init(&item.fh, &s->vdev);
|
||||
item.itv = itv;
|
||||
item.type = s->type;
|
||||
|
||||
/* See if the stream is available */
|
||||
if (ivtv_claim_stream(&item, item.type)) {
|
||||
/* No, it's already in use */
|
||||
v4l2_fh_exit(&item.fh);
|
||||
snd_ivtv_unlock(itvsc);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@ -325,6 +325,7 @@ struct ivtv_queue {
|
||||
};
|
||||
|
||||
struct ivtv; /* forward reference */
|
||||
struct ivtv_open_id;
|
||||
|
||||
struct ivtv_stream {
|
||||
/* These first four fields are always set, even if the stream
|
||||
@ -335,7 +336,7 @@ struct ivtv_stream {
|
||||
int type; /* stream type */
|
||||
u32 caps; /* V4L2 capabilities */
|
||||
|
||||
struct v4l2_fh *fh; /* pointer to the streaming filehandle */
|
||||
struct ivtv_open_id *id; /* pointer to the streaming ivtv_open_id */
|
||||
spinlock_t qlock; /* locks access to the queues */
|
||||
unsigned long s_flags; /* status flags, see above */
|
||||
int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */
|
||||
|
||||
@ -50,16 +50,16 @@ int ivtv_claim_stream(struct ivtv_open_id *id, int type)
|
||||
|
||||
if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
|
||||
/* someone already claimed this stream */
|
||||
if (s->fh == &id->fh) {
|
||||
if (s->id == id) {
|
||||
/* yes, this file descriptor did. So that's OK. */
|
||||
return 0;
|
||||
}
|
||||
if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
|
||||
if (s->id == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
|
||||
type == IVTV_ENC_STREAM_TYPE_VBI)) {
|
||||
/* VBI is handled already internally, now also assign
|
||||
the file descriptor to this stream for external
|
||||
reading of the stream. */
|
||||
s->fh = &id->fh;
|
||||
s->id = id;
|
||||
IVTV_DEBUG_INFO("Start Read VBI\n");
|
||||
return 0;
|
||||
}
|
||||
@ -67,7 +67,7 @@ int ivtv_claim_stream(struct ivtv_open_id *id, int type)
|
||||
IVTV_DEBUG_INFO("Stream %d is busy\n", type);
|
||||
return -EBUSY;
|
||||
}
|
||||
s->fh = &id->fh;
|
||||
s->id = id;
|
||||
if (type == IVTV_DEC_STREAM_TYPE_VBI) {
|
||||
/* Enable reinsertion interrupt */
|
||||
ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
|
||||
@ -105,7 +105,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
|
||||
struct ivtv *itv = s->itv;
|
||||
struct ivtv_stream *s_vbi;
|
||||
|
||||
s->fh = NULL;
|
||||
s->id = NULL;
|
||||
if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) &&
|
||||
test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
|
||||
/* this stream is still in use internally */
|
||||
@ -137,7 +137,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
|
||||
/* was already cleared */
|
||||
return;
|
||||
}
|
||||
if (s_vbi->fh) {
|
||||
if (s_vbi->id) {
|
||||
/* VBI stream still claimed by a file descriptor */
|
||||
return;
|
||||
}
|
||||
@ -361,7 +361,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co
|
||||
size_t tot_written = 0;
|
||||
int single_frame = 0;
|
||||
|
||||
if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) {
|
||||
if (atomic_read(&itv->capturing) == 0 && s->id == NULL) {
|
||||
/* shouldn't happen */
|
||||
IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name);
|
||||
return -EIO;
|
||||
@ -831,7 +831,7 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
|
||||
id->type == IVTV_ENC_STREAM_TYPE_VBI) &&
|
||||
test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
|
||||
/* Also used internally, don't stop capturing */
|
||||
s->fh = NULL;
|
||||
s->id = NULL;
|
||||
}
|
||||
else {
|
||||
ivtv_stop_v4l2_encode_stream(s, gop_end);
|
||||
@ -915,7 +915,7 @@ int ivtv_v4l2_close(struct file *filp)
|
||||
v4l2_fh_exit(fh);
|
||||
|
||||
/* Easy case first: this stream was never claimed by us */
|
||||
if (s->fh != &id->fh)
|
||||
if (s->id != id)
|
||||
goto close_done;
|
||||
|
||||
/* 'Unclaim' this stream */
|
||||
|
||||
@ -317,7 +317,7 @@ static void dma_post(struct ivtv_stream *s)
|
||||
ivtv_process_vbi_data(itv, buf, 0, s->type);
|
||||
s->q_dma.bytesused += buf->bytesused;
|
||||
}
|
||||
if (s->fh == NULL) {
|
||||
if (s->id == NULL) {
|
||||
ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
|
||||
return;
|
||||
}
|
||||
@ -342,7 +342,7 @@ static void dma_post(struct ivtv_stream *s)
|
||||
set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
|
||||
}
|
||||
|
||||
if (s->fh)
|
||||
if (s->id)
|
||||
wake_up(&s->waitq);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user