Skip to content

Commit

Permalink
Merge tag 'media/v4.16-3' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/mchehab/linux-media

Pull media fixes from Mauro Carvalho Chehab:

  - some build fixes with randconfigs

  - an m88ds3103 fix to prevent an OOPS if the chip doesn't provide the
    right version during probe (with can happen if the hardware hangs)

  - a potential out of array bounds reference in tvp5150

  - some fixes and improvements in the DVB memory mapped API (added for
    kernel 4.16)

* tag 'media/v4.16-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  media: vb2: Makefile: place vb2-trace together with vb2-core
  media: Don't let tvp5150_get_vbi() go out of vbi_ram_default array
  media: dvb: update buffer mmaped flags and frame counter
  media: dvb: add continuity error indicators for memory mapped buffers
  media: dmxdev: Fix the logic that enables DMA mmap support
  media: dmxdev: fix error code for invalid ioctls
  media: m88ds3103: don't call a non-initalized function
  media: au0828: add VIDEO_V4L2 dependency
  media: dvb: fix DVB_MMAP dependency
  media: dvb: fix DVB_MMAP symbol name
  media: videobuf2: fix build issues with vb2-trace
  media: videobuf2: Add VIDEOBUF2_V4L2 Kconfig option for VB2 V4L2 part
  • Loading branch information
torvalds committed Mar 3, 2018
2 parents d6d0972 + 7dbdd16 commit 7cf901b
Show file tree
Hide file tree
Showing 24 changed files with 329 additions and 175 deletions.
14 changes: 10 additions & 4 deletions Documentation/media/dmx.h.rst.exceptions
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,15 @@ replace typedef dmx_filter_t :c:type:`dmx_filter`
replace typedef dmx_pes_type_t :c:type:`dmx_pes_type`
replace typedef dmx_input_t :c:type:`dmx_input`

ignore symbol DMX_OUT_DECODER
ignore symbol DMX_OUT_TAP
ignore symbol DMX_OUT_TS_TAP
ignore symbol DMX_OUT_TSDEMUX_TAP
replace symbol DMX_BUFFER_FLAG_HAD_CRC32_DISCARD :c:type:`dmx_buffer_flags`
replace symbol DMX_BUFFER_FLAG_TEI :c:type:`dmx_buffer_flags`
replace symbol DMX_BUFFER_PKT_COUNTER_MISMATCH :c:type:`dmx_buffer_flags`
replace symbol DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED :c:type:`dmx_buffer_flags`
replace symbol DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR :c:type:`dmx_buffer_flags`

replace symbol DMX_OUT_DECODER :c:type:`dmx_output`
replace symbol DMX_OUT_TAP :c:type:`dmx_output`
replace symbol DMX_OUT_TS_TAP :c:type:`dmx_output`
replace symbol DMX_OUT_TSDEMUX_TAP :c:type:`dmx_output`

replace ioctl DMX_DQBUF dmx_qbuf
7 changes: 4 additions & 3 deletions Documentation/media/uapi/dvb/dmx-qbuf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ out to disk. Buffers remain locked until dequeued, until the
the device is closed.
Applications call the ``DMX_DQBUF`` ioctl to dequeue a filled
(capturing) buffer from the driver's outgoing queue. They just set the ``reserved`` field array to zero. When ``DMX_DQBUF`` is called with a
pointer to this structure, the driver fills the remaining fields or
returns an error code.
(capturing) buffer from the driver's outgoing queue.
They just set the ``index`` field withe the buffer ID to be queued.
When ``DMX_DQBUF`` is called with a pointer to struct :c:type:`dmx_buffer`,
the driver fills the remaining fields or returns an error code.
By default ``DMX_DQBUF`` blocks when no buffer is in the outgoing
queue. When the ``O_NONBLOCK`` flag was given to the
Expand Down
2 changes: 2 additions & 0 deletions drivers/media/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ config DVB_CORE
config DVB_MMAP
bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
depends on DVB_CORE
depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_CORE
select VIDEOBUF2_VMALLOC
default n
help
This option enables DVB experimental memory-mapped API, with
Expand Down
3 changes: 3 additions & 0 deletions drivers/media/common/videobuf2/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ config VIDEOBUF2_CORE
select DMA_SHARED_BUFFER
tristate

config VIDEOBUF2_V4L2
tristate

config VIDEOBUF2_MEMOPS
tristate
select FRAME_VECTOR
Expand Down
9 changes: 8 additions & 1 deletion drivers/media/common/videobuf2/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
videobuf2-common-objs := videobuf2-core.o

obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o
ifeq ($(CONFIG_TRACEPOINTS),y)
videobuf2-common-objs += vb2-trace.o
endif

obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-common.o
obj-$(CONFIG_VIDEOBUF2_V4L2) += videobuf2-v4l2.o
obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion drivers/media/dvb-core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#

dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
dvb-vb2-$(CONFIG_DVB_MMSP) := dvb_vb2.o
dvb-vb2-$(CONFIG_DVB_MMAP) := dvb_vb2.o

dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \
dvb_ca_en50221.o dvb_frontend.o \
Expand Down
115 changes: 65 additions & 50 deletions drivers/media/dvb-core/dmxdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct dmxdev *dmxdev = dvbdev->priv;
struct dmx_frontend *front;
#ifndef DVB_MMAP
bool need_ringbuffer = false;
#else
const bool need_ringbuffer = true;
#endif

dprintk("%s\n", __func__);

Expand All @@ -144,17 +140,31 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
return -ENODEV;
}

#ifndef DVB_MMAP
dmxdev->may_do_mmap = 0;

/*
* The logic here is a little tricky due to the ifdef.
*
* The ringbuffer is used for both read and mmap.
*
* It is not needed, however, on two situations:
* - Write devices (access with O_WRONLY);
* - For duplex device nodes, opened with O_RDWR.
*/

if ((file->f_flags & O_ACCMODE) == O_RDONLY)
need_ringbuffer = true;
#else
if ((file->f_flags & O_ACCMODE) == O_RDWR) {
else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
#ifdef CONFIG_DVB_MMAP
dmxdev->may_do_mmap = 1;
need_ringbuffer = true;
#else
mutex_unlock(&dmxdev->mutex);
return -EOPNOTSUPP;
#endif
}
}
#endif

if (need_ringbuffer) {
void *mem;
Expand All @@ -169,8 +179,9 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
return -ENOMEM;
}
dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",
file->f_flags & O_NONBLOCK);
if (dmxdev->may_do_mmap)
dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",
file->f_flags & O_NONBLOCK);
dvbdev->readers--;
}

Expand Down Expand Up @@ -200,11 +211,6 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev = file->private_data;
struct dmxdev *dmxdev = dvbdev->priv;
#ifndef DVB_MMAP
bool need_ringbuffer = false;
#else
const bool need_ringbuffer = true;
#endif

mutex_lock(&dmxdev->mutex);

Expand All @@ -213,15 +219,14 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
dmxdev->demux->connect_frontend(dmxdev->demux,
dmxdev->dvr_orig_fe);
}
#ifndef DVB_MMAP
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
need_ringbuffer = true;
#endif

if (need_ringbuffer) {
if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx);
dvb_vb2_release(&dmxdev->dvr_vb2_ctx);
if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||
dmxdev->may_do_mmap) {
if (dmxdev->may_do_mmap) {
if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx);
dvb_vb2_release(&dmxdev->dvr_vb2_ctx);
}
dvbdev->readers++;
if (dmxdev->dvr_buffer.data) {
void *mem = dmxdev->dvr_buffer.data;
Expand Down Expand Up @@ -380,7 +385,8 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)

static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len,
struct dmx_section_filter *filter)
struct dmx_section_filter *filter,
u32 *buffer_flags)
{
struct dmxdev_filter *dmxdevfilter = filter->priv;
int ret;
Expand All @@ -399,10 +405,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
dprintk("section callback %*ph\n", 6, buffer1);
if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
buffer1, buffer1_len);
buffer1, buffer1_len,
buffer_flags);
if (ret == buffer1_len)
ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
buffer2, buffer2_len);
buffer2, buffer2_len,
buffer_flags);
} else {
ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
buffer1, buffer1_len);
Expand All @@ -422,11 +430,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,

static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len,
struct dmx_ts_feed *feed)
struct dmx_ts_feed *feed,
u32 *buffer_flags)
{
struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer;
#ifdef DVB_MMAP
#ifdef CONFIG_DVB_MMAP
struct dvb_vb2_ctx *ctx;
#endif
int ret;
Expand All @@ -440,20 +449,22 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
if (dmxdevfilter->params.pes.output == DMX_OUT_TAP ||
dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) {
buffer = &dmxdevfilter->buffer;
#ifdef DVB_MMAP
#ifdef CONFIG_DVB_MMAP
ctx = &dmxdevfilter->vb2_ctx;
#endif
} else {
buffer = &dmxdevfilter->dev->dvr_buffer;
#ifdef DVB_MMAP
#ifdef CONFIG_DVB_MMAP
ctx = &dmxdevfilter->dev->dvr_vb2_ctx;
#endif
}

if (dvb_vb2_is_streaming(ctx)) {
ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len);
ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len,
buffer_flags);
if (ret == buffer1_len)
ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len);
ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len,
buffer_flags);
} else {
if (buffer->error) {
spin_unlock(&dmxdevfilter->dev->lock);
Expand Down Expand Up @@ -802,6 +813,12 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
mutex_init(&dmxdevfilter->mutex);
file->private_data = dmxdevfilter;

#ifdef CONFIG_DVB_MMAP
dmxdev->may_do_mmap = 1;
#else
dmxdev->may_do_mmap = 0;
#endif

dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter",
file->f_flags & O_NONBLOCK);
Expand Down Expand Up @@ -1111,7 +1128,7 @@ static int dvb_demux_do_ioctl(struct file *file,
mutex_unlock(&dmxdevfilter->mutex);
break;

#ifdef DVB_MMAP
#ifdef CONFIG_DVB_MMAP
case DMX_REQBUFS:
if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
mutex_unlock(&dmxdev->mutex);
Expand Down Expand Up @@ -1160,7 +1177,7 @@ static int dvb_demux_do_ioctl(struct file *file,
break;
#endif
default:
ret = -EINVAL;
ret = -ENOTTY;
break;
}
mutex_unlock(&dmxdev->mutex);
Expand Down Expand Up @@ -1199,13 +1216,16 @@ static __poll_t dvb_demux_poll(struct file *file, poll_table *wait)
return mask;
}

#ifdef DVB_MMAP
#ifdef CONFIG_DVB_MMAP
static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)
{
struct dmxdev_filter *dmxdevfilter = file->private_data;
struct dmxdev *dmxdev = dmxdevfilter->dev;
int ret;

if (!dmxdev->may_do_mmap)
return -ENOTTY;

if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;

Expand Down Expand Up @@ -1249,7 +1269,7 @@ static const struct file_operations dvb_demux_fops = {
.release = dvb_demux_release,
.poll = dvb_demux_poll,
.llseek = default_llseek,
#ifdef DVB_MMAP
#ifdef CONFIG_DVB_MMAP
.mmap = dvb_demux_mmap,
#endif
};
Expand Down Expand Up @@ -1280,7 +1300,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
ret = dvb_dvr_set_buffer_size(dmxdev, arg);
break;

#ifdef DVB_MMAP
#ifdef CONFIG_DVB_MMAP
case DMX_REQBUFS:
ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg);
break;
Expand All @@ -1304,7 +1324,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
break;
#endif
default:
ret = -EINVAL;
ret = -ENOTTY;
break;
}
mutex_unlock(&dmxdev->mutex);
Expand All @@ -1322,11 +1342,6 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
struct dvb_device *dvbdev = file->private_data;
struct dmxdev *dmxdev = dvbdev->priv;
__poll_t mask = 0;
#ifndef DVB_MMAP
bool need_ringbuffer = false;
#else
const bool need_ringbuffer = true;
#endif

dprintk("%s\n", __func__);

Expand All @@ -1337,11 +1352,8 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)

poll_wait(file, &dmxdev->dvr_buffer.queue, wait);

#ifndef DVB_MMAP
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
need_ringbuffer = true;
#endif
if (need_ringbuffer) {
if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||
dmxdev->may_do_mmap) {
if (dmxdev->dvr_buffer.error)
mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI | EPOLLERR);

Expand All @@ -1353,13 +1365,16 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
return mask;
}

#ifdef DVB_MMAP
#ifdef CONFIG_DVB_MMAP
static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)
{
struct dvb_device *dvbdev = file->private_data;
struct dmxdev *dmxdev = dvbdev->priv;
int ret;

if (!dmxdev->may_do_mmap)
return -ENOTTY;

if (dmxdev->exit)
return -ENODEV;

Expand All @@ -1381,7 +1396,7 @@ static const struct file_operations dvb_dvr_fops = {
.release = dvb_dvr_release,
.poll = dvb_dvr_poll,
.llseek = default_llseek,
#ifdef DVB_MMAP
#ifdef CONFIG_DVB_MMAP
.mmap = dvb_dvr_mmap,
#endif
};
Expand Down
Loading

0 comments on commit 7cf901b

Please sign in to comment.