mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2023-10-10 13:37:43 +02:00
adapt to mainline kernel changes
This commit is contained in:
parent
e9ed73b929
commit
b51b7c0598
@ -1,19 +1,9 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* dmxdev.c - DVB demultiplexer device
|
||||
*
|
||||
* Copyright (C) 2000 Ralph Metzler & Marcus Metzler
|
||||
* for convergence integrated media GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "dmxdev: " fmt
|
||||
@ -415,6 +405,7 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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,
|
||||
@ -479,10 +470,10 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
|
||||
u32 *buffer_flags)
|
||||
{
|
||||
struct dmxdev_filter *dmxdevfilter = feed->priv;
|
||||
struct dvb_ringbuffer *buffer;
|
||||
#ifdef CONFIG_DVB_MMAP
|
||||
struct dvb_vb2_ctx *ctx;
|
||||
#endif
|
||||
struct dvb_ringbuffer *buffer;
|
||||
int ret;
|
||||
|
||||
spin_lock(&dmxdevfilter->dev->lock);
|
||||
@ -849,6 +840,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
|
||||
if (mutex_lock_interruptible(&dmxdev->mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (dmxdev->exit) {
|
||||
mutex_unlock(&dmxdev->mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (i = 0; i < dmxdev->filternum; i++)
|
||||
if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
|
||||
break;
|
||||
@ -1485,7 +1481,7 @@ static const struct dvb_device dvbdev_dvr = {
|
||||
|
||||
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
|
||||
{
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
if (dmxdev->demux->open(dmxdev->demux) < 0)
|
||||
return -EUSERS;
|
||||
@ -1508,21 +1504,36 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
|
||||
DMXDEV_STATE_FREE);
|
||||
}
|
||||
|
||||
dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
|
||||
ret = dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
|
||||
DVB_DEVICE_DEMUX, dmxdev->filternum);
|
||||
dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
|
||||
if (ret < 0)
|
||||
goto err_register_dvbdev;
|
||||
|
||||
ret = dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
|
||||
dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
|
||||
if (ret < 0)
|
||||
goto err_register_dvr_dvbdev;
|
||||
|
||||
dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
|
||||
|
||||
return 0;
|
||||
|
||||
err_register_dvr_dvbdev:
|
||||
dvb_unregister_device(dmxdev->dvbdev);
|
||||
err_register_dvbdev:
|
||||
vfree(dmxdev->filter);
|
||||
dmxdev->filter = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dvb_dmxdev_init);
|
||||
|
||||
void dvb_dmxdev_release(struct dmxdev *dmxdev)
|
||||
{
|
||||
mutex_lock(&dmxdev->mutex);
|
||||
dmxdev->exit = 1;
|
||||
mutex_unlock(&dmxdev->mutex);
|
||||
|
||||
if (dmxdev->dvbdev->users > 1) {
|
||||
wait_event(dmxdev->dvbdev->wait_queue,
|
||||
dmxdev->dvbdev->users == 1);
|
||||
|
@ -164,7 +164,7 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
dvb_free_device(ca->dvbdev);
|
||||
dvb_device_put(ca->dvbdev);
|
||||
for (i = 0; i < ca->slot_count; i++)
|
||||
vfree(ca->slot_info[i].rx_buffer.data);
|
||||
|
||||
|
@ -1,20 +1,10 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* dvb_demux.c - DVB kernel demux API
|
||||
*
|
||||
* Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de>
|
||||
* & Marcus Metzler <marcus@convergence.de>
|
||||
* for convergence integrated media GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "dvb_demux: " fmt
|
||||
@ -256,7 +246,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
|
||||
{
|
||||
struct dvb_demux *demux = feed->demux;
|
||||
struct dmx_section_feed *sec = &feed->feed.sec;
|
||||
u16 limit, seclen, n;
|
||||
u16 limit, seclen;
|
||||
|
||||
if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
|
||||
return 0;
|
||||
@ -285,7 +275,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
|
||||
/* to be sure always set secbuf */
|
||||
sec->secbuf = sec->secbuf_base + sec->secbufp;
|
||||
|
||||
for (n = 0; sec->secbufp + 2 < limit; n++) {
|
||||
while (sec->secbufp + 2 < limit) {
|
||||
seclen = section_length(sec->secbuf);
|
||||
if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
|
||||
|| seclen + sec->secbufp > limit)
|
||||
|
@ -141,7 +141,7 @@ static void __dvb_frontend_free(struct dvb_frontend *fe)
|
||||
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||
|
||||
if (fepriv)
|
||||
dvb_free_device(fepriv->dvbdev);
|
||||
dvb_device_put(fepriv->dvbdev);
|
||||
|
||||
dvb_frontend_invoke_release(fe, fe->ops.release);
|
||||
|
||||
@ -924,6 +924,7 @@ static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe,
|
||||
|
||||
/* If the standard is for satellite, convert frequencies to kHz */
|
||||
switch (c->delivery_system) {
|
||||
case SYS_DSS:
|
||||
case SYS_DVBS:
|
||||
case SYS_DVBS2:
|
||||
case SYS_TURBO:
|
||||
@ -949,6 +950,7 @@ static u32 dvb_frontend_get_stepsize(struct dvb_frontend *fe)
|
||||
u32 step = max(fe_step, tuner_step);
|
||||
|
||||
switch (c->delivery_system) {
|
||||
case SYS_DSS:
|
||||
case SYS_DVBS:
|
||||
case SYS_DVBS2:
|
||||
case SYS_TURBO:
|
||||
@ -980,6 +982,7 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
|
||||
|
||||
/* range check: symbol rate */
|
||||
switch (c->delivery_system) {
|
||||
case SYS_DSS:
|
||||
case SYS_DVBS:
|
||||
case SYS_DVBS2:
|
||||
case SYS_TURBO:
|
||||
@ -1047,6 +1050,10 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
|
||||
c->input = NO_INPUT;
|
||||
|
||||
switch (c->delivery_system) {
|
||||
case SYS_DSS:
|
||||
c->modulation = QPSK;
|
||||
c->rolloff = ROLLOFF_20;
|
||||
break;
|
||||
case SYS_DVBS:
|
||||
case SYS_DVBS2:
|
||||
case SYS_TURBO:
|
||||
@ -1839,6 +1846,7 @@ static void prepare_tuning_algo_parameters(struct dvb_frontend *fe)
|
||||
} else {
|
||||
/* default values */
|
||||
switch (c->delivery_system) {
|
||||
case SYS_DSS:
|
||||
case SYS_DVBS:
|
||||
case SYS_DVBS2:
|
||||
case SYS_ISDBS:
|
||||
@ -2312,6 +2320,9 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
|
||||
case SYS_DVBC_ANNEX_C:
|
||||
rolloff = 113;
|
||||
break;
|
||||
case SYS_DSS:
|
||||
rolloff = 120;
|
||||
break;
|
||||
case SYS_DVBS:
|
||||
case SYS_TURBO:
|
||||
case SYS_ISDBS:
|
||||
@ -2582,8 +2593,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
|
||||
|
||||
case FE_DISEQC_SEND_BURST:
|
||||
if (fe->ops.diseqc_send_burst) {
|
||||
err = fe->ops.diseqc_send_burst(fe,
|
||||
(enum fe_sec_mini_cmd)parg);
|
||||
err = fe->ops.diseqc_send_burst(fe, (long)parg);
|
||||
fepriv->state = FESTATE_DISEQC;
|
||||
fepriv->status = 0;
|
||||
}
|
||||
@ -2591,9 +2601,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
|
||||
|
||||
case FE_SET_TONE:
|
||||
if (fe->ops.set_tone) {
|
||||
err = fe->ops.set_tone(fe,
|
||||
(enum fe_sec_tone_mode)parg);
|
||||
fepriv->tone = (enum fe_sec_tone_mode)parg;
|
||||
fepriv->tone = (long)parg;
|
||||
err = fe->ops.set_tone(fe, fepriv->tone);
|
||||
fepriv->state = FESTATE_DISEQC;
|
||||
fepriv->status = 0;
|
||||
}
|
||||
@ -2601,9 +2610,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
|
||||
|
||||
case FE_SET_VOLTAGE:
|
||||
if (fe->ops.set_voltage) {
|
||||
err = fe->ops.set_voltage(fe,
|
||||
(enum fe_sec_voltage)parg);
|
||||
fepriv->voltage = (enum fe_sec_voltage)parg;
|
||||
fepriv->voltage = (long)parg;
|
||||
err = fe->ops.set_voltage(fe, fepriv->voltage);
|
||||
fepriv->state = FESTATE_DISEQC;
|
||||
fepriv->status = 0;
|
||||
}
|
||||
@ -2767,7 +2775,6 @@ typedef unsigned int __poll_t;
|
||||
#define EPOLLOUT POLLOUT
|
||||
#endif
|
||||
|
||||
|
||||
static __poll_t dvb_frontend_poll(struct file *file, struct poll_table_struct *wait)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
@ -2796,7 +2803,17 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
|
||||
if (fe->exit == DVB_FE_DEVICE_REMOVED)
|
||||
return -ENODEV;
|
||||
|
||||
if (adapter->mfe_shared) {
|
||||
if (adapter->mfe_shared == 2) {
|
||||
mutex_lock(&adapter->mfe_lock);
|
||||
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
|
||||
if (adapter->mfe_dvbdev &&
|
||||
!adapter->mfe_dvbdev->writers) {
|
||||
mutex_unlock(&adapter->mfe_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
adapter->mfe_dvbdev = dvbdev;
|
||||
}
|
||||
} else if (adapter->mfe_shared) {
|
||||
mutex_lock(&adapter->mfe_lock);
|
||||
|
||||
if (!adapter->mfe_dvbdev)
|
||||
@ -2974,7 +2991,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe)
|
||||
else if (fe->ops.tuner_ops.sleep)
|
||||
ret = fe->ops.tuner_ops.sleep(fe);
|
||||
|
||||
if (fe->ops.sleep)
|
||||
if (fe->ops.suspend)
|
||||
ret = fe->ops.suspend(fe);
|
||||
else if (fe->ops.sleep)
|
||||
ret = fe->ops.sleep(fe);
|
||||
|
||||
return ret;
|
||||
@ -2990,7 +3009,9 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
|
||||
fe->id);
|
||||
|
||||
fe->exit = DVB_FE_DEVICE_RESUME;
|
||||
if (fe->ops.init)
|
||||
if (fe->ops.resume)
|
||||
ret = fe->ops.resume(fe);
|
||||
else if (fe->ops.init)
|
||||
ret = fe->ops.init(fe);
|
||||
|
||||
if (fe->ops.tuner_ops.resume)
|
||||
@ -3024,6 +3045,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
|
||||
.name = fe->ops.info.name,
|
||||
#endif
|
||||
};
|
||||
int ret;
|
||||
|
||||
dev_dbg(dvb->device, "%s:\n", __func__);
|
||||
|
||||
@ -3053,9 +3075,15 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
|
||||
fe->dvb = dvb;
|
||||
fepriv->inversion = INVERSION_OFF;
|
||||
|
||||
dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
|
||||
ret = dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
|
||||
fe, DVB_DEVICE_FRONTEND, 0);
|
||||
|
||||
if (ret) {
|
||||
dvb_frontend_put(fe);
|
||||
mutex_unlock(&frontend_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(fe->dvb->device,
|
||||
"DVB: registering adapter %i frontend %i (%s)...\n",
|
||||
fe->dvb->num, fepriv->dvbdev->id, fe->ops.info.name);
|
||||
|
@ -60,6 +60,9 @@
|
||||
|
||||
#include <media/dvb_demux.h>
|
||||
#include <media/dvb_net.h>
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
|
||||
#include <linux/nospec.h>
|
||||
#endif
|
||||
|
||||
static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
|
||||
{
|
||||
@ -1062,7 +1065,7 @@ static int dvb_net_feed_start(struct net_device *dev)
|
||||
int ret = 0, i;
|
||||
struct dvb_net_priv *priv = netdev_priv(dev);
|
||||
struct dmx_demux *demux = priv->demux;
|
||||
const unsigned char *mac = (unsigned char *) dev->dev_addr;
|
||||
const unsigned char *mac = (const unsigned char *) dev->dev_addr;
|
||||
|
||||
netdev_dbg(dev, "rx_mode %i\n", priv->rx_mode);
|
||||
mutex_lock(&priv->mutex);
|
||||
@ -1483,14 +1486,21 @@ static int dvb_net_do_ioctl(struct file *file,
|
||||
struct net_device *netdev;
|
||||
struct dvb_net_priv *priv_data;
|
||||
struct dvb_net_if *dvbnetif = parg;
|
||||
int if_num = dvbnetif->if_num;
|
||||
|
||||
if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
|
||||
!dvbnet->state[dvbnetif->if_num]) {
|
||||
if (if_num >= DVB_NET_DEVICES_MAX) {
|
||||
ret = -EINVAL;
|
||||
goto ioctl_error;
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
|
||||
if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX);
|
||||
#endif
|
||||
if (!dvbnet->state[if_num]) {
|
||||
ret = -EINVAL;
|
||||
goto ioctl_error;
|
||||
}
|
||||
|
||||
netdev = dvbnet->device[dvbnetif->if_num];
|
||||
netdev = dvbnet->device[if_num];
|
||||
|
||||
priv_data = netdev_priv(netdev);
|
||||
dvbnetif->pid=priv_data->pid;
|
||||
@ -1543,14 +1553,21 @@ static int dvb_net_do_ioctl(struct file *file,
|
||||
struct net_device *netdev;
|
||||
struct dvb_net_priv *priv_data;
|
||||
struct __dvb_net_if_old *dvbnetif = parg;
|
||||
int if_num = dvbnetif->if_num;
|
||||
|
||||
if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
|
||||
!dvbnet->state[dvbnetif->if_num]) {
|
||||
if (if_num >= DVB_NET_DEVICES_MAX) {
|
||||
ret = -EINVAL;
|
||||
goto ioctl_error;
|
||||
}
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
|
||||
if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX);
|
||||
#endif
|
||||
if (!dvbnet->state[if_num]) {
|
||||
ret = -EINVAL;
|
||||
goto ioctl_error;
|
||||
}
|
||||
|
||||
netdev = dvbnet->device[dvbnetif->if_num];
|
||||
netdev = dvbnet->device[if_num];
|
||||
|
||||
priv_data = netdev_priv(netdev);
|
||||
dvbnetif->pid=priv_data->pid;
|
||||
|
@ -63,7 +63,7 @@ int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
|
||||
* this pairs with smp_store_release() in dvb_ringbuffer_write(),
|
||||
* dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset()
|
||||
*
|
||||
* for memory barriers also see Documentation/core-api/circular-buffers.txt
|
||||
* for memory barriers also see Documentation/core-api/circular-buffers.rst
|
||||
*/
|
||||
return (rbuf->pread == smp_load_acquire(&rbuf->pwrite));
|
||||
#endif
|
||||
@ -75,7 +75,7 @@ ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
|
||||
{
|
||||
ssize_t free;
|
||||
|
||||
/* ACCESS_ONCE() to load read pointer on writer side
|
||||
/* READ_ONCE() to load read pointer on writer side
|
||||
* this pairs with smp_store_release() in dvb_ringbuffer_read(),
|
||||
* dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(),
|
||||
* or dvb_ringbuffer_reset()
|
||||
@ -171,7 +171,7 @@ ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, si
|
||||
#else
|
||||
/* smp_store_release() for read pointer update to ensure
|
||||
* that buf is not overwritten until read is complete,
|
||||
* this pairs with ACCESS_ONCE() in dvb_ringbuffer_free()
|
||||
* this pairs with READ_ONCE() in dvb_ringbuffer_free()
|
||||
*/
|
||||
smp_store_release(&rbuf->pread, 0);
|
||||
#endif
|
||||
@ -203,7 +203,7 @@ void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
|
||||
#else
|
||||
/* smp_store_release() for read pointer update to ensure
|
||||
* that buf is not overwritten until read is complete,
|
||||
* this pairs with ACCESS_ONCE() in dvb_ringbuffer_free()
|
||||
* this pairs with READ_ONCE() in dvb_ringbuffer_free()
|
||||
*/
|
||||
smp_store_release(&rbuf->pread, 0);
|
||||
#endif
|
||||
@ -391,7 +391,7 @@ ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t*
|
||||
idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
|
||||
}
|
||||
|
||||
consumed = idx - rbuf->pread;
|
||||
consumed = (idx - rbuf->pread);
|
||||
if (consumed < 0)
|
||||
consumed += rbuf->size;
|
||||
|
||||
|
@ -5,10 +5,6 @@
|
||||
* Copyright (C) 2015 Samsung Electronics
|
||||
*
|
||||
* Author: jh1009.sung@samsung.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
@ -358,6 +354,12 @@ 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)
|
||||
{
|
||||
struct vb2_queue *q = &ctx->vb_q;
|
||||
|
||||
if (b->index >= q->num_buffers) {
|
||||
dprintk(1, "[%s] buffer index out of range\n", ctx->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
vb2_core_querybuf(&ctx->vb_q, b->index, b);
|
||||
dprintk(3, "[%s] index=%d\n", ctx->name, b->index);
|
||||
return 0;
|
||||
@ -382,8 +384,13 @@ 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)
|
||||
{
|
||||
struct vb2_queue *q = &ctx->vb_q;
|
||||
int ret;
|
||||
|
||||
if (b->index >= q->num_buffers) {
|
||||
dprintk(1, "[%s] buffer index out of range\n", ctx->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = vb2_core_qbuf(&ctx->vb_q, b->index, b, NULL);
|
||||
if (ret) {
|
||||
dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
|
||||
|
@ -1,20 +1,10 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* dvbdev.c
|
||||
*
|
||||
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
|
||||
* & Marcus Metzler <marcus@convergence.de>
|
||||
* for convergence integrated media GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "dvbdev: " fmt
|
||||
@ -118,7 +108,7 @@ static int dvb_device_open(struct inode *inode, struct file *file)
|
||||
new_fops = fops_get(dvbdev->fops);
|
||||
if (!new_fops)
|
||||
goto fail;
|
||||
file->private_data = dvbdev;
|
||||
file->private_data = dvb_device_get(dvbdev);
|
||||
replace_fops(file, new_fops);
|
||||
if (file->f_op->open)
|
||||
err = file->f_op->open(inode, file);
|
||||
@ -182,6 +172,9 @@ int dvb_generic_release(struct inode *inode, struct file *file)
|
||||
}
|
||||
|
||||
dvbdev->users++;
|
||||
|
||||
dvb_device_put(dvbdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_generic_release);
|
||||
@ -264,7 +257,7 @@ static void dvb_media_device_free(struct dvb_device *dvbdev)
|
||||
static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
|
||||
const char *name, int npads)
|
||||
{
|
||||
int i, ret = 0;
|
||||
int i;
|
||||
|
||||
dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
|
||||
GFP_KERNEL);
|
||||
@ -281,6 +274,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
|
||||
for (i = 0; i < npads; i++) {
|
||||
struct media_pad *pads = &dvbdev->tsout_pads[i];
|
||||
struct media_entity *entity = &dvbdev->tsout_entity[i];
|
||||
int ret;
|
||||
|
||||
entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
|
||||
if (!entity->name)
|
||||
@ -353,6 +347,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
|
||||
GFP_KERNEL);
|
||||
if (!dvbdev->pads) {
|
||||
kfree(dvbdev->entity);
|
||||
dvbdev->entity = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
@ -499,6 +494,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
||||
}
|
||||
|
||||
memcpy(dvbdev, template, sizeof(struct dvb_device));
|
||||
kref_init(&dvbdev->ref);
|
||||
dvbdev->type = type;
|
||||
dvbdev->id = id;
|
||||
dvbdev->adapter = adap;
|
||||
@ -529,7 +525,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
||||
#endif
|
||||
|
||||
dvbdev->minor = minor;
|
||||
dvb_minors[minor] = dvbdev;
|
||||
dvb_minors[minor] = dvb_device_get(dvbdev);
|
||||
up_write(&minor_rwsem);
|
||||
|
||||
ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
|
||||
@ -574,6 +570,7 @@ void dvb_remove_device(struct dvb_device *dvbdev)
|
||||
|
||||
down_write(&minor_rwsem);
|
||||
dvb_minors[dvbdev->minor] = NULL;
|
||||
dvb_device_put(dvbdev);
|
||||
up_write(&minor_rwsem);
|
||||
|
||||
dvb_media_device_free(dvbdev);
|
||||
@ -585,21 +582,34 @@ void dvb_remove_device(struct dvb_device *dvbdev)
|
||||
EXPORT_SYMBOL(dvb_remove_device);
|
||||
|
||||
|
||||
void dvb_free_device(struct dvb_device *dvbdev)
|
||||
static void dvb_free_device(struct kref *ref)
|
||||
{
|
||||
if (!dvbdev)
|
||||
return;
|
||||
struct dvb_device *dvbdev = container_of(ref, struct dvb_device, ref);
|
||||
|
||||
kfree (dvbdev->fops);
|
||||
kfree (dvbdev);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_free_device);
|
||||
|
||||
|
||||
struct dvb_device *dvb_device_get(struct dvb_device *dvbdev)
|
||||
{
|
||||
kref_get(&dvbdev->ref);
|
||||
return dvbdev;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_device_get);
|
||||
|
||||
|
||||
void dvb_device_put(struct dvb_device *dvbdev)
|
||||
{
|
||||
if (dvbdev)
|
||||
kref_put(&dvbdev->ref, dvb_free_device);
|
||||
}
|
||||
|
||||
|
||||
void dvb_unregister_device(struct dvb_device *dvbdev)
|
||||
{
|
||||
dvb_remove_device(dvbdev);
|
||||
dvb_free_device(dvbdev);
|
||||
dvb_device_put(dvbdev);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_unregister_device);
|
||||
|
||||
@ -1041,9 +1051,13 @@ EXPORT_SYMBOL_GPL(dvb_module_release);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (KERNEL_VERSION(6, 2, 0) > LINUX_VERSION_CODE)
|
||||
static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
#else
|
||||
static int dvb_uevent(const struct device *dev, struct kobj_uevent_env *env)
|
||||
#endif
|
||||
{
|
||||
struct dvb_device *dvbdev = dev_get_drvdata(dev);
|
||||
const struct dvb_device *dvbdev = dev_get_drvdata(dev);
|
||||
|
||||
add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
|
||||
add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]);
|
||||
@ -1051,9 +1065,13 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (KERNEL_VERSION(6, 2, 0) > LINUX_VERSION_CODE)
|
||||
static char *dvb_devnode(struct device *dev, umode_t *mode)
|
||||
#else
|
||||
static char *dvb_devnode(const struct device *dev, umode_t *mode)
|
||||
#endif
|
||||
{
|
||||
struct dvb_device *dvbdev = dev_get_drvdata(dev);
|
||||
const struct dvb_device *dvbdev = dev_get_drvdata(dev);
|
||||
|
||||
return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d",
|
||||
dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);
|
||||
|
@ -280,7 +280,28 @@ enum fe_spectral_inversion {
|
||||
* @FEC_3_5: Forward Error Correction Code 3/5
|
||||
* @FEC_9_10: Forward Error Correction Code 9/10
|
||||
* @FEC_2_5: Forward Error Correction Code 2/5
|
||||
*
|
||||
* @FEC_1_3: Forward Error Correction Code 1/3
|
||||
* @FEC_1_4: Forward Error Correction Code 1/4
|
||||
* @FEC_5_9: Forward Error Correction Code 5/9
|
||||
* @FEC_7_9: Forward Error Correction Code 7/9
|
||||
* @FEC_8_15: Forward Error Correction Code 8/15
|
||||
* @FEC_11_15: Forward Error Correction Code 11/15
|
||||
* @FEC_13_18: Forward Error Correction Code 13/18
|
||||
* @FEC_9_20: Forward Error Correction Code 9/20
|
||||
* @FEC_11_20: Forward Error Correction Code 11/20
|
||||
* @FEC_23_36: Forward Error Correction Code 23/36
|
||||
* @FEC_25_36: Forward Error Correction Code 25/36
|
||||
* @FEC_13_45: Forward Error Correction Code 13/45
|
||||
* @FEC_26_45: Forward Error Correction Code 26/45
|
||||
* @FEC_28_45: Forward Error Correction Code 28/45
|
||||
* @FEC_32_45: Forward Error Correction Code 32/45
|
||||
* @FEC_77_90: Forward Error Correction Code 77/90
|
||||
* @FEC_11_45: Forward Error Correction Code 11/45
|
||||
* @FEC_4_15: Forward Error Correction Code 4/15
|
||||
* @FEC_14_45: Forward Error Correction Code 14/45
|
||||
* @FEC_7_15: Forward Error Correction Code 7/15
|
||||
* @FEC_29_45: Forward Error Correction Code 29/45
|
||||
* @FEC_31_45: Forward Error Correction Code 31/45
|
||||
* Please note that not all FEC types are supported by a given standard.
|
||||
*/
|
||||
enum fe_code_rate {
|
||||
@ -297,8 +318,28 @@ enum fe_code_rate {
|
||||
FEC_3_5,
|
||||
FEC_9_10,
|
||||
FEC_2_5,
|
||||
FEC_1_4,
|
||||
FEC_1_3,
|
||||
FEC_1_4,
|
||||
FEC_5_9,
|
||||
FEC_7_9,
|
||||
FEC_8_15,
|
||||
FEC_11_15,
|
||||
FEC_13_18,
|
||||
FEC_9_20,
|
||||
FEC_11_20,
|
||||
FEC_23_36,
|
||||
FEC_25_36,
|
||||
FEC_13_45,
|
||||
FEC_26_45,
|
||||
FEC_28_45,
|
||||
FEC_32_45,
|
||||
FEC_77_90,
|
||||
FEC_11_45,
|
||||
FEC_4_15,
|
||||
FEC_14_45,
|
||||
FEC_7_15,
|
||||
FEC_29_45,
|
||||
FEC_31_45,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -317,6 +358,16 @@ enum fe_code_rate {
|
||||
* @APSK_32: 32-APSK modulation
|
||||
* @DQPSK: DQPSK modulation
|
||||
* @QAM_4_NR: 4-QAM-NR modulation
|
||||
* @QAM_1024: 1024-QAM modulation
|
||||
* @QAM_4096: 4096-QAM modulation
|
||||
* @APSK_8_L: 8APSK-L modulation
|
||||
* @APSK_16_L: 16APSK-L modulation
|
||||
* @APSK_32_L: 32APSK-L modulation
|
||||
* @APSK_64: 64APSK modulation
|
||||
* @APSK_64_L: 64APSK-L modulation
|
||||
* @APSK_128: 128APSK modulation
|
||||
* @APSK_256: 256APSK modulation
|
||||
* @APSK_256_L: 256APSK-L modulation
|
||||
*
|
||||
* Please note that not all modulations are supported by a given standard.
|
||||
*
|
||||
@ -336,9 +387,16 @@ enum fe_modulation {
|
||||
APSK_32,
|
||||
DQPSK,
|
||||
QAM_4_NR,
|
||||
QAM_1024,
|
||||
QAM_4096,
|
||||
APSK_8_L,
|
||||
APSK_16_L,
|
||||
APSK_32_L,
|
||||
APSK_64,
|
||||
APSK_64_L,
|
||||
APSK_128,
|
||||
APSK_256,
|
||||
APSK_256_L,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -393,6 +451,7 @@ enum fe_transmit_mode {
|
||||
* @GUARD_INTERVAL_PN420: PN length 420 (1/4)
|
||||
* @GUARD_INTERVAL_PN595: PN length 595 (1/6)
|
||||
* @GUARD_INTERVAL_PN945: PN length 945 (1/9)
|
||||
* @GUARD_INTERVAL_1_64: Guard interval 1/64
|
||||
*
|
||||
* Please note that not all guard intervals are supported by a given standard.
|
||||
*/
|
||||
@ -408,6 +467,7 @@ enum fe_guard_interval {
|
||||
GUARD_INTERVAL_PN420,
|
||||
GUARD_INTERVAL_PN595,
|
||||
GUARD_INTERVAL_PN945,
|
||||
GUARD_INTERVAL_1_64,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -561,6 +621,9 @@ enum fe_pilot {
|
||||
* @ROLLOFF_20: Roloff factor: α=20%
|
||||
* @ROLLOFF_25: Roloff factor: α=25%
|
||||
* @ROLLOFF_AUTO: Auto-detect the roloff factor.
|
||||
* @ROLLOFF_15: Rolloff factor: α=15%
|
||||
* @ROLLOFF_10: Rolloff factor: α=10%
|
||||
* @ROLLOFF_5: Rolloff factor: α=5%
|
||||
*
|
||||
* .. note:
|
||||
*
|
||||
@ -587,6 +650,8 @@ enum fe_rolloff {
|
||||
* Cable TV: DVB-C following ITU-T J.83 Annex B spec (ClearQAM)
|
||||
* @SYS_DVBC_ANNEX_C:
|
||||
* Cable TV: DVB-C following ITU-T J.83 Annex C spec
|
||||
* @SYS_DVBC2:
|
||||
* Cable TV: DVB-C2
|
||||
* @SYS_ISDBC:
|
||||
* Cable TV: ISDB-C (no drivers yet)
|
||||
* @SYS_DVBT:
|
||||
@ -604,7 +669,7 @@ enum fe_rolloff {
|
||||
* @SYS_DVBS:
|
||||
* Satellite TV: DVB-S
|
||||
* @SYS_DVBS2:
|
||||
* Satellite TV: DVB-S2
|
||||
* Satellite TV: DVB-S2 and DVB-S2X
|
||||
* @SYS_TURBO:
|
||||
* Satellite TV: DVB-S Turbo
|
||||
* @SYS_ISDBS:
|
||||
@ -714,7 +779,7 @@ enum atscmh_rs_frame_mode {
|
||||
};
|
||||
|
||||
/**
|
||||
* enum atscmh_rs_code_mode
|
||||
* enum atscmh_rs_code_mode - ATSC-M/H Reed Solomon modes
|
||||
* @ATSCMH_RSCODE_211_187: Reed Solomon code (211,187).
|
||||
* @ATSCMH_RSCODE_223_187: Reed Solomon code (223,187).
|
||||
* @ATSCMH_RSCODE_235_187: Reed Solomon code (235,187).
|
||||
|
@ -369,6 +369,10 @@ struct dvb_frontend_internal_info {
|
||||
* allocated by the driver.
|
||||
* @init: callback function used to initialize the tuner device.
|
||||
* @sleep: callback function used to put the tuner to sleep.
|
||||
* @suspend: callback function used to inform that the Kernel will
|
||||
* suspend.
|
||||
* @resume: callback function used to inform that the Kernel is
|
||||
* resuming from suspend.
|
||||
* @write: callback function used by some demod legacy drivers to
|
||||
* allow other drivers to write data into their registers.
|
||||
* Should not be used on new drivers.
|
||||
@ -438,7 +442,6 @@ struct dvb_frontend_internal_info {
|
||||
* @analog_ops: pointer to &struct analog_demod_ops
|
||||
*/
|
||||
struct dvb_frontend_ops {
|
||||
|
||||
struct dvb_frontend_internal_info info;
|
||||
|
||||
u8 delsys[MAX_DELSYS];
|
||||
@ -449,6 +452,8 @@ struct dvb_frontend_ops {
|
||||
|
||||
int (*init)(struct dvb_frontend* fe);
|
||||
int (*sleep)(struct dvb_frontend* fe);
|
||||
int (*suspend)(struct dvb_frontend *fe);
|
||||
int (*resume)(struct dvb_frontend *fe);
|
||||
|
||||
int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
|
||||
|
||||
@ -765,7 +770,8 @@ void dvb_frontend_detach(struct dvb_frontend *fe);
|
||||
* &dvb_frontend_ops.tuner_ops.suspend\(\) is available, it calls it. Otherwise,
|
||||
* it will call &dvb_frontend_ops.tuner_ops.sleep\(\), if available.
|
||||
*
|
||||
* It will also call &dvb_frontend_ops.sleep\(\) to put the demod to suspend.
|
||||
* It will also call &dvb_frontend_ops.suspend\(\) to put the demod to suspend,
|
||||
* if available. Otherwise it will call &dvb_frontend_ops.sleep\(\).
|
||||
*
|
||||
* The drivers should also call dvb_frontend_suspend\(\) as part of their
|
||||
* handler for the &device_driver.suspend\(\).
|
||||
@ -779,7 +785,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe);
|
||||
*
|
||||
* This function resumes the usual operation of the tuner after resume.
|
||||
*
|
||||
* In order to resume the frontend, it calls the demod &dvb_frontend_ops.init\(\).
|
||||
* In order to resume the frontend, it calls the demod
|
||||
* &dvb_frontend_ops.resume\(\) if available. Otherwise it calls demod
|
||||
* &dvb_frontend_ops.init\(\).
|
||||
*
|
||||
* If &dvb_frontend_ops.tuner_ops.resume\(\) is available, It, it calls it.
|
||||
* Otherwise,t will call &dvb_frontend_ops.tuner_ops.init\(\), if available.
|
||||
|
@ -214,7 +214,7 @@ extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
|
||||
* @buf: Buffer to write.
|
||||
* @len: Length of buffer (currently limited to 65535 bytes max).
|
||||
*
|
||||
* Return: Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
|
||||
* Return: Number of bytes written, or -EFAULT, -ENOMEM, -EINVAL.
|
||||
*/
|
||||
extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8 *buf,
|
||||
size_t len);
|
||||
|
@ -96,7 +96,11 @@ struct dvb_frontend;
|
||||
* @device: pointer to struct device
|
||||
* @module: pointer to struct module
|
||||
* @mfe_shared: indicates mutually exclusive frontends.
|
||||
* Use of this flag is currently deprecated.
|
||||
* 1 = legacy exclusion behavior: blocking any open() call
|
||||
* 2 = enhanced exclusion behavior, emulating the standard
|
||||
* behavior of busy frontends: allowing read-only sharing
|
||||
* and otherwise returning immediately with -EBUSY when any
|
||||
* of the frontends is already opened with write access.
|
||||
* @mfe_dvbdev: Frontend device in use, in the case of MFE
|
||||
* @mfe_lock: Lock to prevent using the other frontends when MFE is
|
||||
* used.
|
||||
@ -135,6 +139,7 @@ struct dvb_adapter {
|
||||
* struct dvb_device - represents a DVB device node
|
||||
*
|
||||
* @list_head: List head with all DVB devices
|
||||
* @ref: reference counter
|
||||
* @fops: pointer to struct file_operations
|
||||
* @adapter: pointer to the adapter that holds this device node
|
||||
* @type: type of the device, as defined by &enum dvb_device_type.
|
||||
@ -165,6 +170,7 @@ struct dvb_adapter {
|
||||
*/
|
||||
struct dvb_device {
|
||||
struct list_head list_head;
|
||||
struct kref ref;
|
||||
const struct file_operations *fops;
|
||||
struct dvb_adapter *adapter;
|
||||
enum dvb_device_type type;
|
||||
@ -196,6 +202,20 @@ struct dvb_device {
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* dvb_device_get - Increase dvb_device reference
|
||||
*
|
||||
* @dvbdev: pointer to struct dvb_device
|
||||
*/
|
||||
struct dvb_device *dvb_device_get(struct dvb_device *dvbdev);
|
||||
|
||||
/**
|
||||
* dvb_device_put - Decrease dvb_device reference
|
||||
*
|
||||
* @dvbdev: pointer to struct dvb_device
|
||||
*/
|
||||
void dvb_device_put(struct dvb_device *dvbdev);
|
||||
|
||||
/**
|
||||
* dvb_register_adapter - Registers a new DVB adapter
|
||||
*
|
||||
@ -240,29 +260,16 @@ int dvb_register_device(struct dvb_adapter *adap,
|
||||
/**
|
||||
* dvb_remove_device - Remove a registered DVB device
|
||||
*
|
||||
* This does not free memory. To do that, call dvb_free_device().
|
||||
* This does not free memory. dvb_free_device() will do that when
|
||||
* reference counter is empty
|
||||
*
|
||||
* @dvbdev: pointer to struct dvb_device
|
||||
*/
|
||||
void dvb_remove_device(struct dvb_device *dvbdev);
|
||||
|
||||
/**
|
||||
* dvb_free_device - Free memory occupied by a DVB device.
|
||||
*
|
||||
* Call dvb_unregister_device() before calling this function.
|
||||
*
|
||||
* @dvbdev: pointer to struct dvb_device
|
||||
*/
|
||||
void dvb_free_device(struct dvb_device *dvbdev);
|
||||
|
||||
/**
|
||||
* dvb_unregister_device - Unregisters a DVB device
|
||||
*
|
||||
* This is a combination of dvb_remove_device() and dvb_free_device().
|
||||
* Using this function is usually a mistake, and is often an indicator
|
||||
* for a use-after-free bug (when a userspace process keeps a file
|
||||
* handle to a detached device).
|
||||
*
|
||||
* @dvbdev: pointer to struct dvb_device
|
||||
*/
|
||||
void dvb_unregister_device(struct dvb_device *dvbdev);
|
||||
|
Loading…
Reference in New Issue
Block a user