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: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
Родитель
651d666605
Коммит
4021053ed5
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче