Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4021053e authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

media: dvb-core: make DVB mmap API optional



This API is still experimental. Make it optional, allowing to
compile the code without it.

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 651d6666
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -144,6 +144,18 @@ config DVB_CORE
	default y
	select CRC32

config DVB_MMAP
	bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
	depends on DVB_CORE
	default n
	help
	  This option enables DVB experimental memory-mapped API, with
	  reduces the number of context switches to read DVB buffers, as
	  the buffers can use mmap() syscalls.

	  Support for it is experimental. Use with care. If unsure,
	  say N.

config DVB_NET
	bool "DVB Network Support"
	default (NET && INET)
+2 −1
Original line number Diff line number Diff line
@@ -4,9 +4,10 @@
#

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

dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o		 	\
		 dvb_ca_en50221.o dvb_frontend.o 		\
		 $(dvb-net-y) dvb_ringbuffer.o dvb_vb2.o dvb_math.o
		 $(dvb-net-y) dvb_ringbuffer.o $(dvb-vb2-y) dvb_math.o

obj-$(CONFIG_DVB_CORE) += dvb-core.o
+58 −8
Original line number Diff line number Diff line
@@ -128,6 +128,11 @@ 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__);

@@ -139,8 +144,19 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
		return -ENODEV;
	}

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

	if (need_ringbuffer) {
		void *mem;

		if (!dvbdev->readers) {
@@ -184,6 +200,11 @@ 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);

@@ -192,8 +213,12 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
		dmxdev->demux->connect_frontend(dmxdev->demux,
						dmxdev->dvr_orig_fe);
	}
	if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||
	    ((file->f_flags & O_ACCMODE) == O_RDWR)) {
#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);
@@ -359,6 +384,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
{
	struct dmxdev_filter *dmxdevfilter = filter->priv;
	int ret;

	if (!dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx) &&
	    dmxdevfilter->buffer.error) {
		wake_up(&dmxdevfilter->buffer.queue);
@@ -400,7 +426,9 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
{
	struct dmxdev_filter *dmxdevfilter = feed->priv;
	struct dvb_ringbuffer *buffer;
#ifdef DVB_MMAP
	struct dvb_vb2_ctx *ctx;
#endif
	int ret;

	spin_lock(&dmxdevfilter->dev->lock);
@@ -412,10 +440,14 @@ 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
		ctx = &dmxdevfilter->vb2_ctx;
#endif
	} else {
		buffer = &dmxdevfilter->dev->dvr_buffer;
#ifdef DVB_MMAP
		ctx = &dmxdevfilter->dev->dvr_vb2_ctx;
#endif
	}

	if (dvb_vb2_is_streaming(ctx)) {
@@ -1079,6 +1111,7 @@ static int dvb_demux_do_ioctl(struct file *file,
		mutex_unlock(&dmxdevfilter->mutex);
		break;

#ifdef DVB_MMAP
	case DMX_REQBUFS:
		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
			mutex_unlock(&dmxdev->mutex);
@@ -1125,7 +1158,7 @@ static int dvb_demux_do_ioctl(struct file *file,
		ret = dvb_vb2_dqbuf(&dmxdevfilter->vb2_ctx, parg);
		mutex_unlock(&dmxdevfilter->mutex);
		break;

#endif
	default:
		ret = -EINVAL;
		break;
@@ -1166,6 +1199,7 @@ static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
	return mask;
}

#ifdef DVB_MMAP
static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct dmxdev_filter *dmxdevfilter = file->private_data;
@@ -1186,6 +1220,7 @@ static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)

	return ret;
}
#endif

static int dvb_demux_release(struct inode *inode, struct file *file)
{
@@ -1214,7 +1249,9 @@ static const struct file_operations dvb_demux_fops = {
	.release = dvb_demux_release,
	.poll = dvb_demux_poll,
	.llseek = default_llseek,
#ifdef DVB_MMAP
	.mmap = dvb_demux_mmap,
#endif
};

static const struct dvb_device dvbdev_demux = {
@@ -1243,6 +1280,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
		ret = dvb_dvr_set_buffer_size(dmxdev, arg);
		break;

#ifdef DVB_MMAP
	case DMX_REQBUFS:
		ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg);
		break;
@@ -1264,7 +1302,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
	case DMX_DQBUF:
		ret = dvb_vb2_dqbuf(&dmxdev->dvr_vb2_ctx, parg);
		break;

#endif
	default:
		ret = -EINVAL;
		break;
@@ -1284,6 +1322,11 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
	struct dvb_device *dvbdev = file->private_data;
	struct dmxdev *dmxdev = dvbdev->priv;
	unsigned int mask = 0;
#ifndef DVB_MMAP
	bool need_ringbuffer = false;
#else
	const bool need_ringbuffer = true;
#endif

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

@@ -1294,8 +1337,11 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)

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

	if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||
	    ((file->f_flags & O_ACCMODE) == O_RDWR)) {
#ifndef DVB_MMAP
	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
		need_ringbuffer = true;
#endif
	if (need_ringbuffer) {
		if (dmxdev->dvr_buffer.error)
			mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);

@@ -1307,6 +1353,7 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
	return mask;
}

#ifdef DVB_MMAP
static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct dvb_device *dvbdev = file->private_data;
@@ -1323,6 +1370,7 @@ static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)
	mutex_unlock(&dmxdev->mutex);
	return ret;
}
#endif

static const struct file_operations dvb_dvr_fops = {
	.owner = THIS_MODULE,
@@ -1333,7 +1381,9 @@ static const struct file_operations dvb_dvr_fops = {
	.release = dvb_dvr_release,
	.poll = dvb_dvr_poll,
	.llseek = default_llseek,
#ifdef DVB_MMAP
	.mmap = dvb_dvr_mmap,
#endif
};

static const struct dvb_device dvbdev_dvr = {
+26 −4
Original line number Diff line number Diff line
@@ -54,13 +54,37 @@ struct dvb_vb2_ctx {
	char	name[DVB_VB2_NAME_MAX + 1];
};

int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking);
int dvb_vb2_release(struct dvb_vb2_ctx *ctx);
int dvb_vb2_stream_on(struct dvb_vb2_ctx *ctx);
int dvb_vb2_stream_off(struct dvb_vb2_ctx *ctx);
#ifndef DVB_MMAP
static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx,
			       const char *name, int non_blocking)
{
	return 0;
};
static inline int dvb_vb2_release(struct dvb_vb2_ctx *ctx)
{
	return 0;
};
#define dvb_vb2_is_streaming(ctx) (0)
#define dvb_vb2_fill_buffer(ctx, file, wait) (0)

static inline unsigned int dvb_vb2_poll(struct dvb_vb2_ctx *ctx,
					struct file *file,
					poll_table *wait)
{
	return 0;
}
#else
int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking);
int dvb_vb2_release(struct dvb_vb2_ctx *ctx);
int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx);
int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
			const unsigned char *src, int len);
unsigned int dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file,
			  poll_table *wait);
#endif


int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req);
int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
@@ -68,7 +92,5 @@ int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp);
int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
int dvb_vb2_mmap(struct dvb_vb2_ctx *ctx, struct vm_area_struct *vma);
unsigned int dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file,
			  poll_table *wait);

#endif /* _DVB_VB2_H */