1
0
mirror of https://github.com/DigitalDevices/dddvb.git synced 2023-10-10 13:37:43 +02:00

adapt to latest mainline dvb-core

This commit is contained in:
rjkm 2022-01-14 20:13:34 +01:00
parent 90e6d4806b
commit b6d2a37ac2
6 changed files with 215 additions and 174 deletions

View File

@ -766,7 +766,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
ret = dmxdev->demux->allocate_section_feed(dmxdev->demux, ret = dmxdev->demux->allocate_section_feed(dmxdev->demux,
secfeed, secfeed,
dvb_dmxdev_section_callback); dvb_dmxdev_section_callback);
if (ret < 0) { if (!*secfeed) {
pr_err("DVB (%s): could not alloc feed\n", pr_err("DVB (%s): could not alloc feed\n",
__func__); __func__);
return ret; return ret;

View File

@ -197,7 +197,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
u8 *ebuf, int ecount, u8 flags); u8 *ebuf, int ecount, u8 flags);
/** /**
* Safely find needle in haystack. * findstr - Safely find needle in haystack.
* *
* @haystack: Buffer to look in. * @haystack: Buffer to look in.
* @hlen: Number of bytes in haystack. * @hlen: Number of bytes in haystack.
@ -629,8 +629,8 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot to read from. * @slot: Slot to read from.
* @ebuf: If non-NULL, the data will be written to this buffer. If NULL, * @ebuf: If non-NULL, the data will be written to this buffer. If NULL,
* the data will be added into the buffering system as a normal * the data will be added into the buffering system as a normal
* fragment. * fragment.
* @ecount: Size of ebuf. Ignored if ebuf is NULL. * @ecount: Size of ebuf. Ignored if ebuf is NULL.
* *
* return: Number of bytes read, or < 0 on error * return: Number of bytes read, or < 0 on error
@ -783,7 +783,7 @@ exit:
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot to write to. * @slot: Slot to write to.
* @buf: The data in this buffer is treated as a complete link-level packet to * @buf: The data in this buffer is treated as a complete link-level packet to
* be written. * be written.
* @bytes_write: Size of ebuf. * @bytes_write: Size of ebuf.
* *
* return: Number of bytes written, or < 0 on error. * return: Number of bytes written, or < 0 on error.
@ -1013,7 +1013,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
/* EN50221 thread functions */ /* EN50221 thread functions */
/** /**
* Wake up the DVB CA thread * dvb_ca_en50221_thread_wakeup - Wake up the DVB CA thread
* *
* @ca: CA instance. * @ca: CA instance.
*/ */
@ -1027,7 +1027,7 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
} }
/** /**
* Update the delay used by the thread. * dvb_ca_en50221_thread_update_delay - Update the delay used by the thread.
* *
* @ca: CA instance. * @ca: CA instance.
*/ */
@ -1085,7 +1085,7 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
} }
/** /**
* Poll if the CAM is gone. * dvb_ca_en50221_poll_cam_gone - Poll if the CAM is gone.
* *
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot to process. * @slot: Slot to process.
@ -1116,7 +1116,8 @@ static int dvb_ca_en50221_poll_cam_gone(struct dvb_ca_private *ca, int slot)
} }
/** /**
* Thread state machine for one CA slot to perform the data transfer. * dvb_ca_en50221_thread_state_machine - Thread state machine for one CA slot
* to perform the data transfer.
* *
* @ca: CA instance. * @ca: CA instance.
* @slot: Slot to process. * @slot: Slot to process.
@ -1268,7 +1269,7 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca,
sl->slot_state = DVB_CA_SLOTSTATE_RUNNING; sl->slot_state = DVB_CA_SLOTSTATE_RUNNING;
dvb_ca_en50221_thread_update_delay(ca); dvb_ca_en50221_thread_update_delay(ca);
pr_info("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", pr_info("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n",
ca->dvbdev->adapter->num); ca->dvbdev->adapter->num);
break; break;
case DVB_CA_SLOTSTATE_RUNNING: case DVB_CA_SLOTSTATE_RUNNING:
@ -1347,13 +1348,14 @@ static int dvb_ca_en50221_thread(void *data)
/* EN50221 IO interface functions */ /* EN50221 IO interface functions */
/** /**
* Real ioctl implementation. * dvb_ca_en50221_io_do_ioctl - Real ioctl implementation.
* NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
* *
* @file: File concerned. * @file: File concerned.
* @cmd: IOCTL command. * @cmd: IOCTL command.
* @parg: Associated argument. * @parg: Associated argument.
* *
* NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
*
* return: 0 on success, <0 on error. * return: 0 on success, <0 on error.
*/ */
static int dvb_ca_en50221_io_do_ioctl(struct file *file, static int dvb_ca_en50221_io_do_ioctl(struct file *file,
@ -1407,7 +1409,9 @@ static int dvb_ca_en50221_io_do_ioctl(struct file *file,
err = -EINVAL; err = -EINVAL;
goto out_unlock; goto out_unlock;
} }
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
slot = array_index_nospec(slot, ca->slot_count);
#endif
info->type = CA_CI_LINK; info->type = CA_CI_LINK;
info->flags = 0; info->flags = 0;
sl = &ca->slot_info[slot]; sl = &ca->slot_info[slot];
@ -1431,7 +1435,7 @@ out_unlock:
} }
/** /**
* Wrapper for ioctl implementation. * dvb_ca_en50221_io_ioctl - Wrapper for ioctl implementation.
* *
* @file: File concerned. * @file: File concerned.
* @cmd: IOCTL command. * @cmd: IOCTL command.
@ -1446,7 +1450,7 @@ static long dvb_ca_en50221_io_ioctl(struct file *file,
} }
/** /**
* Implementation of write() syscall. * dvb_ca_en50221_io_write - Implementation of write() syscall.
* *
* @file: File structure. * @file: File structure.
* @buf: Source buffer. * @buf: Source buffer.
@ -1603,7 +1607,7 @@ nextslot:
} }
/** /**
* Implementation of read() syscall. * dvb_ca_en50221_io_read - Implementation of read() syscall.
* *
* @file: File structure. * @file: File structure.
* @buf: Destination buffer. * @buf: Destination buffer.
@ -1714,7 +1718,7 @@ exit:
} }
/** /**
* Implementation of file open syscall. * dvb_ca_en50221_io_open - Implementation of file open syscall.
* *
* @inode: Inode concerned. * @inode: Inode concerned.
* @file: File concerned. * @file: File concerned.
@ -1764,7 +1768,7 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
} }
/** /**
* Implementation of file close syscall. * dvb_ca_en50221_io_release - Implementation of file close syscall.
* *
* @inode: Inode concerned. * @inode: Inode concerned.
* @file: File concerned. * @file: File concerned.
@ -1793,7 +1797,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
} }
/** /**
* Implementation of poll() syscall. * dvb_ca_en50221_io_poll - Implementation of poll() syscall.
* *
* @file: File concerned. * @file: File concerned.
* @wait: poll wait table. * @wait: poll wait table.
@ -1855,7 +1859,7 @@ static const struct dvb_device dvbdev_ca = {
/* Initialisation/shutdown functions */ /* Initialisation/shutdown functions */
/** /**
* Initialise a new DVB CA EN50221 interface device. * dvb_ca_en50221_init - Initialise a new DVB CA EN50221 interface device.
* *
* @dvb_adapter: DVB adapter to attach the new CA device to. * @dvb_adapter: DVB adapter to attach the new CA device to.
* @pubca: The dvb_ca instance. * @pubca: The dvb_ca instance.
@ -1947,7 +1951,7 @@ exit:
EXPORT_SYMBOL(dvb_ca_en50221_init); EXPORT_SYMBOL(dvb_ca_en50221_init);
/** /**
* Release a DVB CA EN50221 interface device. * dvb_ca_en50221_release - Release a DVB CA EN50221 interface device.
* *
* @pubca: The associated dvb_ca instance. * @pubca: The associated dvb_ca instance.
*/ */

View File

@ -20,6 +20,7 @@
#include <linux/version.h> #include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
#include <linux/nospec.h>
#else #else
#include <linux/sched.h> #include <linux/sched.h>
#endif #endif
@ -487,6 +488,10 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp; struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp;
if (fepriv->max_drift)
dev_warn(fe->dvb->device,
"Frontend requested software zigzag, but didn't set the frequency step size\n");
/* if we've got no parameters, just keep idling */ /* if we've got no parameters, just keep idling */
if (fepriv->state & FESTATE_IDLE) { if (fepriv->state & FESTATE_IDLE) {
fepriv->delay = 3 * HZ; fepriv->delay = 3 * HZ;
@ -990,6 +995,7 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
fe->ops.info.symbol_rate_max); fe->ops.info.symbol_rate_max);
return -EINVAL; return -EINVAL;
} }
break;
default: default:
break; break;
} }
@ -1065,108 +1071,100 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
return 0; return 0;
} }
#define _DTV_CMD(n, s, b) \ #define _DTV_CMD(n) \
[n] = { \ [n] = #n
.name = #n, \
.cmd = n, \
.set = s,\
.buffer = b \
}
struct dtv_cmds_h { static char *dtv_cmds[DTV_MAX_COMMAND + 1] = {
char *name; /* A display name for debugging purposes */ _DTV_CMD(DTV_TUNE),
_DTV_CMD(DTV_CLEAR),
__u32 cmd; /* A unique ID */
/* Flags */
__u32 set:1; /* Either a set or get property */
__u32 buffer:1; /* Does this property use the buffer? */
__u32 reserved:30; /* Align */
};
static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
_DTV_CMD(DTV_TUNE, 1, 0),
_DTV_CMD(DTV_CLEAR, 1, 0),
/* Set */ /* Set */
_DTV_CMD(DTV_FREQUENCY, 1, 0), _DTV_CMD(DTV_FREQUENCY),
_DTV_CMD(DTV_BANDWIDTH_HZ, 1, 0), _DTV_CMD(DTV_BANDWIDTH_HZ),
_DTV_CMD(DTV_MODULATION, 1, 0), _DTV_CMD(DTV_MODULATION),
_DTV_CMD(DTV_INVERSION, 1, 0), _DTV_CMD(DTV_INVERSION),
_DTV_CMD(DTV_DISEQC_MASTER, 1, 1), _DTV_CMD(DTV_DISEQC_MASTER),
_DTV_CMD(DTV_SYMBOL_RATE, 1, 0), _DTV_CMD(DTV_SYMBOL_RATE),
_DTV_CMD(DTV_INNER_FEC, 1, 0), _DTV_CMD(DTV_INNER_FEC),
_DTV_CMD(DTV_VOLTAGE, 1, 0), _DTV_CMD(DTV_VOLTAGE),
_DTV_CMD(DTV_TONE, 1, 0), _DTV_CMD(DTV_TONE),
_DTV_CMD(DTV_PILOT, 1, 0), _DTV_CMD(DTV_PILOT),
_DTV_CMD(DTV_ROLLOFF, 1, 0), _DTV_CMD(DTV_ROLLOFF),
_DTV_CMD(DTV_DELIVERY_SYSTEM, 1, 0), _DTV_CMD(DTV_DELIVERY_SYSTEM),
_DTV_CMD(DTV_HIERARCHY, 1, 0), _DTV_CMD(DTV_HIERARCHY),
_DTV_CMD(DTV_CODE_RATE_HP, 1, 0), _DTV_CMD(DTV_CODE_RATE_HP),
_DTV_CMD(DTV_CODE_RATE_LP, 1, 0), _DTV_CMD(DTV_CODE_RATE_LP),
_DTV_CMD(DTV_GUARD_INTERVAL, 1, 0), _DTV_CMD(DTV_GUARD_INTERVAL),
_DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0), _DTV_CMD(DTV_TRANSMISSION_MODE),
_DTV_CMD(DTV_INTERLEAVING, 1, 0), _DTV_CMD(DTV_INTERLEAVING),
_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0), _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION),
_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0), _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING),
_DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0), _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID),
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0), _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX),
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0), _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT),
_DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0), _DTV_CMD(DTV_ISDBT_LAYER_ENABLED),
_DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERA_FEC),
_DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION),
_DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT),
_DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING),
_DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERB_FEC),
_DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION),
_DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT),
_DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING),
_DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERC_FEC),
_DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION),
_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT),
_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0), _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING),
_DTV_CMD(DTV_STREAM_ID, 1, 0), _DTV_CMD(DTV_STREAM_ID),
_DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0), _DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY),
_DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, 1, 0), _DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX),
_DTV_CMD(DTV_LNA, 1, 0), _DTV_CMD(DTV_LNA),
_DTV_CMD(DTV_INPUT, 1, 0), _DTV_CMD(DTV_INPUT),
/* Get */ /* Get */
_DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1), _DTV_CMD(DTV_DISEQC_SLAVE_REPLY),
_DTV_CMD(DTV_API_VERSION, 0, 0), _DTV_CMD(DTV_API_VERSION),
_DTV_CMD(DTV_ENUM_DELSYS, 0, 0), _DTV_CMD(DTV_ENUM_DELSYS),
_DTV_CMD(DTV_ATSCMH_PARADE_ID, 1, 0), _DTV_CMD(DTV_ATSCMH_PARADE_ID),
_DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE, 1, 0), _DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE),
_DTV_CMD(DTV_ATSCMH_FIC_VER, 0, 0), _DTV_CMD(DTV_ATSCMH_FIC_VER),
_DTV_CMD(DTV_ATSCMH_NOG, 0, 0), _DTV_CMD(DTV_ATSCMH_NOG),
_DTV_CMD(DTV_ATSCMH_TNOG, 0, 0), _DTV_CMD(DTV_ATSCMH_TNOG),
_DTV_CMD(DTV_ATSCMH_SGN, 0, 0), _DTV_CMD(DTV_ATSCMH_SGN),
_DTV_CMD(DTV_ATSCMH_PRC, 0, 0), _DTV_CMD(DTV_ATSCMH_PRC),
_DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE, 0, 0), _DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE),
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI, 0, 0), _DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI),
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC, 0, 0), _DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC),
_DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE, 0, 0), _DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_A, 0, 0), _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_A),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B, 0, 0), _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C, 0, 0), _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D, 0, 0), _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D),
/* Statistics API */ /* Statistics API */
_DTV_CMD(DTV_STAT_SIGNAL_STRENGTH, 0, 0), _DTV_CMD(DTV_STAT_SIGNAL_STRENGTH),
_DTV_CMD(DTV_STAT_CNR, 0, 0), _DTV_CMD(DTV_STAT_CNR),
_DTV_CMD(DTV_STAT_PRE_ERROR_BIT_COUNT, 0, 0), _DTV_CMD(DTV_STAT_PRE_ERROR_BIT_COUNT),
_DTV_CMD(DTV_STAT_PRE_TOTAL_BIT_COUNT, 0, 0), _DTV_CMD(DTV_STAT_PRE_TOTAL_BIT_COUNT),
_DTV_CMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0, 0), _DTV_CMD(DTV_STAT_POST_ERROR_BIT_COUNT),
_DTV_CMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0, 0), _DTV_CMD(DTV_STAT_POST_TOTAL_BIT_COUNT),
_DTV_CMD(DTV_STAT_ERROR_BLOCK_COUNT, 0, 0), _DTV_CMD(DTV_STAT_ERROR_BLOCK_COUNT),
_DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0), _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT),
}; };
static char *dtv_cmd_name(u32 cmd)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
cmd = array_index_nospec(cmd, DTV_MAX_COMMAND);
#endif
return dtv_cmds[cmd];
}
/* Synchronise the legacy tuning parameters into the cache, so that demodulator /* Synchronise the legacy tuning parameters into the cache, so that demodulator
* drivers can use a single set_frontend tuning function, regardless of whether * drivers can use a single set_frontend tuning function, regardless of whether
* it's being used for the legacy or new API, reducing code and complexity. * it's being used for the legacy or new API, reducing code and complexity.
@ -1349,8 +1347,9 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
struct file *file) struct file *file)
{ {
int ncaps; int ncaps;
unsigned int len = 1;
switch(tvp->cmd) { switch (tvp->cmd) {
case DTV_ENUM_DELSYS: case DTV_ENUM_DELSYS:
ncaps = 0; ncaps = 0;
while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) { while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
@ -1358,6 +1357,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
ncaps++; ncaps++;
} }
tvp->u.buffer.len = ncaps; tvp->u.buffer.len = ncaps;
len = ncaps;
break; break;
case DTV_FREQUENCY: case DTV_FREQUENCY:
tvp->u.data = c->frequency; tvp->u.data = c->frequency;
@ -1543,27 +1543,51 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
/* Fill quality measures */ /* Fill quality measures */
case DTV_STAT_SIGNAL_STRENGTH: case DTV_STAT_SIGNAL_STRENGTH:
tvp->u.st = c->strength; tvp->u.st = c->strength;
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
len = tvp->u.buffer.len;
break; break;
case DTV_STAT_CNR: case DTV_STAT_CNR:
tvp->u.st = c->cnr; tvp->u.st = c->cnr;
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
len = tvp->u.buffer.len;
break; break;
case DTV_STAT_PRE_ERROR_BIT_COUNT: case DTV_STAT_PRE_ERROR_BIT_COUNT:
tvp->u.st = c->pre_bit_error; tvp->u.st = c->pre_bit_error;
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
len = tvp->u.buffer.len;
break; break;
case DTV_STAT_PRE_TOTAL_BIT_COUNT: case DTV_STAT_PRE_TOTAL_BIT_COUNT:
tvp->u.st = c->pre_bit_count; tvp->u.st = c->pre_bit_count;
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
len = tvp->u.buffer.len;
break; break;
case DTV_STAT_POST_ERROR_BIT_COUNT: case DTV_STAT_POST_ERROR_BIT_COUNT:
tvp->u.st = c->post_bit_error; tvp->u.st = c->post_bit_error;
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
len = tvp->u.buffer.len;
break; break;
case DTV_STAT_POST_TOTAL_BIT_COUNT: case DTV_STAT_POST_TOTAL_BIT_COUNT:
tvp->u.st = c->post_bit_count; tvp->u.st = c->post_bit_count;
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
len = tvp->u.buffer.len;
break; break;
case DTV_STAT_ERROR_BLOCK_COUNT: case DTV_STAT_ERROR_BLOCK_COUNT:
tvp->u.st = c->block_error; tvp->u.st = c->block_error;
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
len = tvp->u.buffer.len;
break; break;
case DTV_STAT_TOTAL_BLOCK_COUNT: case DTV_STAT_TOTAL_BLOCK_COUNT:
tvp->u.st = c->block_count; tvp->u.st = c->block_count;
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
len = tvp->u.buffer.len;
break; break;
default: default:
dev_dbg(fe->dvb->device, dev_dbg(fe->dvb->device,
@ -1572,18 +1596,13 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
return -EINVAL; return -EINVAL;
} }
if (!dtv_cmds[tvp->cmd].buffer) if (len < 1)
dev_dbg(fe->dvb->device, len = 1;
"%s: GET cmd 0x%08x (%s) = 0x%08x\n",
__func__, tvp->cmd, dtv_cmds[tvp->cmd].name, dev_dbg(fe->dvb->device,
tvp->u.data); "%s: GET cmd 0x%08x (%s) len %d: %*ph\n",
else __func__, tvp->cmd, dtv_cmd_name(tvp->cmd),
dev_dbg(fe->dvb->device, tvp->u.buffer.len, tvp->u.buffer.len, tvp->u.buffer.data);
"%s: GET cmd 0x%08x (%s) len %d: %*ph\n",
__func__,
tvp->cmd, dtv_cmds[tvp->cmd].name,
tvp->u.buffer.len,
tvp->u.buffer.len, tvp->u.buffer.data);
return 0; return 0;
} }
@ -1806,6 +1825,53 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe)
return emulate_delivery_system(fe, delsys); return emulate_delivery_system(fe, delsys);
} }
static void prepare_tuning_algo_parameters(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dvb_frontend_tune_settings fetunesettings = { 0 };
/* get frontend-specific tuning settings */
if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) {
fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
fepriv->max_drift = fetunesettings.max_drift;
fepriv->step_size = fetunesettings.step_size;
} else {
/* default values */
switch (c->delivery_system) {
case SYS_DVBS:
case SYS_DVBS2:
case SYS_ISDBS:
case SYS_TURBO:
case SYS_DVBC_ANNEX_A:
case SYS_DVBC_ANNEX_C:
fepriv->min_delay = HZ / 20;
fepriv->step_size = c->symbol_rate / 16000;
fepriv->max_drift = c->symbol_rate / 2000;
break;
case SYS_DVBT:
case SYS_DVBT2:
case SYS_ISDBT:
case SYS_DTMB:
fepriv->min_delay = HZ / 20;
fepriv->step_size = dvb_frontend_get_stepsize(fe) * 2;
fepriv->max_drift = fepriv->step_size + 1;
break;
default:
/*
* FIXME: This sounds wrong! if freqency_stepsize is
* defined by the frontend, why not use it???
*/
fepriv->min_delay = HZ / 20;
fepriv->step_size = 0; /* no zigzag */
fepriv->max_drift = 0;
break;
}
}
if (dvb_override_tune_delay > 0)
fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000;
}
/** /**
* dtv_property_process_set - Sets a single DTV property * dtv_property_process_set - Sets a single DTV property
* @fe: Pointer to &struct dvb_frontend * @fe: Pointer to &struct dvb_frontend
@ -1834,7 +1900,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
else else
dev_dbg(fe->dvb->device, dev_dbg(fe->dvb->device,
"%s: SET cmd 0x%08x (%s) to 0x%08x\n", "%s: SET cmd 0x%08x (%s) to 0x%08x\n",
__func__, cmd, dtv_cmds[cmd].name, data); __func__, cmd, dtv_cmd_name(cmd), data);
switch (cmd) { switch (cmd) {
case DTV_CLEAR: case DTV_CLEAR:
/* /*
@ -2204,7 +2270,6 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
{ {
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct dvb_frontend_tune_settings fetunesettings;
u32 rolloff = 0; u32 rolloff = 0;
if (dvb_frontend_check_parameters(fe) < 0) if (dvb_frontend_check_parameters(fe) < 0)
@ -2282,46 +2347,7 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
if (c->hierarchy == HIERARCHY_NONE && c->code_rate_LP == FEC_NONE) if (c->hierarchy == HIERARCHY_NONE && c->code_rate_LP == FEC_NONE)
c->code_rate_LP = FEC_AUTO; c->code_rate_LP = FEC_AUTO;
/* get frontend-specific tuning settings */ prepare_tuning_algo_parameters(fe);
memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) {
fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
fepriv->max_drift = fetunesettings.max_drift;
fepriv->step_size = fetunesettings.step_size;
} else {
/* default values */
switch (c->delivery_system) {
case SYS_DVBS:
case SYS_DVBS2:
case SYS_ISDBS:
case SYS_TURBO:
case SYS_DVBC_ANNEX_A:
case SYS_DVBC_ANNEX_C:
fepriv->min_delay = HZ / 20;
fepriv->step_size = c->symbol_rate / 16000;
fepriv->max_drift = c->symbol_rate / 2000;
break;
case SYS_DVBT:
case SYS_DVBT2:
case SYS_ISDBT:
case SYS_DTMB:
fepriv->min_delay = HZ / 20;
fepriv->step_size = dvb_frontend_get_stepsize(fe) * 2;
fepriv->max_drift = (dvb_frontend_get_stepsize(fe) * 2) + 1;
break;
default:
/*
* FIXME: This sounds wrong! if freqency_stepsize is
* defined by the frontend, why not use it???
*/
fepriv->min_delay = HZ / 20;
fepriv->step_size = 0; /* no zigzag */
fepriv->max_drift = 0;
break;
}
}
if (dvb_override_tune_delay > 0)
fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000;
fepriv->state = FESTATE_RETUNE; fepriv->state = FESTATE_RETUNE;
@ -2336,7 +2362,6 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
return 0; return 0;
} }
static int dvb_get_property(struct dvb_frontend *fe, struct file *file, static int dvb_get_property(struct dvb_frontend *fe, struct file *file,
struct dtv_properties *tvps) struct dtv_properties *tvps)
{ {

View File

@ -215,7 +215,7 @@ static int ule_exthdr_padding(struct dvb_net_priv *p)
} }
/* /*
* Handle ULE extension headers. * Handle ULE extension headers.
* Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding. * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding.
* Returns: >= 0: nr. of bytes consumed by next extension header * Returns: >= 0: nr. of bytes consumed by next extension header
* -1: Mandatory extension header that is not recognized or TEST SNDU; discard. * -1: Mandatory extension header that is not recognized or TEST SNDU; discard.
@ -1018,7 +1018,7 @@ static u8 mask_promisc[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static int dvb_net_filter_sec_set(struct net_device *dev, static int dvb_net_filter_sec_set(struct net_device *dev,
struct dmx_section_filter **secfilter, struct dmx_section_filter **secfilter,
u8 *mac, u8 *mac_mask) const u8 *mac, u8 *mac_mask)
{ {
struct dvb_net_priv *priv = netdev_priv(dev); struct dvb_net_priv *priv = netdev_priv(dev);
int ret; int ret;
@ -1062,7 +1062,7 @@ static int dvb_net_feed_start(struct net_device *dev)
int ret = 0, i; int ret = 0, i;
struct dvb_net_priv *priv = netdev_priv(dev); struct dvb_net_priv *priv = netdev_priv(dev);
struct dmx_demux *demux = priv->demux; struct dmx_demux *demux = priv->demux;
unsigned char *mac = (unsigned char *) dev->dev_addr; const unsigned char *mac = (unsigned char *) dev->dev_addr;
netdev_dbg(dev, "rx_mode %i\n", priv->rx_mode); netdev_dbg(dev, "rx_mode %i\n", priv->rx_mode);
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);

View File

@ -79,13 +79,17 @@ static const char * const dnames[] = {
static const u8 minor_type[] = { static const u8 minor_type[] = {
[DVB_DEVICE_VIDEO] = 0, [DVB_DEVICE_VIDEO] = 0,
[DVB_DEVICE_AUDIO] = 1, [DVB_DEVICE_AUDIO] = 1,
[DVB_DEVICE_SEC] = 2, [DVB_DEVICE_SEC] = 2,
[DVB_DEVICE_FRONTEND] = 3, [DVB_DEVICE_FRONTEND] = 3,
[DVB_DEVICE_DEMUX] = 4, [DVB_DEVICE_DEMUX] = 4,
[DVB_DEVICE_DVR] = 5, [DVB_DEVICE_DVR] = 5,
[DVB_DEVICE_CA] = 6, [DVB_DEVICE_CA] = 6,
[DVB_DEVICE_NET] = 7, [DVB_DEVICE_NET] = 7,
[DVB_DEVICE_OSD] = 8, [DVB_DEVICE_OSD] = 8,
[DVB_DEVICE_CI] = 9,
[DVB_DEVICE_MOD] = 10,
[DVB_DEVICE_NS] = 11,
[DVB_DEVICE_NSD] = 12,
}; };
#define nums2minor(num, type, id) \ #define nums2minor(num, type, id) \
@ -248,6 +252,7 @@ static void dvb_media_device_free(struct dvb_device *dvbdev)
if (dvbdev->adapter->conn) { if (dvbdev->adapter->conn) {
media_device_unregister_entity(dvbdev->adapter->conn); media_device_unregister_entity(dvbdev->adapter->conn);
kfree(dvbdev->adapter->conn);
dvbdev->adapter->conn = NULL; dvbdev->adapter->conn = NULL;
kfree(dvbdev->adapter->conn_pads); kfree(dvbdev->adapter->conn_pads);
dvbdev->adapter->conn_pads = NULL; dvbdev->adapter->conn_pads = NULL;
@ -346,7 +351,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
if (npads) { if (npads) {
dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads), dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
GFP_KERNEL); GFP_KERNEL);
if (!dvbdev->pads){ if (!dvbdev->pads) {
kfree(dvbdev->entity); kfree(dvbdev->entity);
return -ENOMEM; return -ENOMEM;
} }
@ -512,6 +517,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
break; break;
if (minor == MAX_DVB_MINORS) { if (minor == MAX_DVB_MINORS) {
list_del (&dvbdev->list_head);
kfree(dvbdevfops); kfree(dvbdevfops);
kfree(dvbdev); kfree(dvbdev);
up_write(&minor_rwsem); up_write(&minor_rwsem);
@ -532,6 +538,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
__func__); __func__);
dvb_media_device_free(dvbdev); dvb_media_device_free(dvbdev);
list_del (&dvbdev->list_head);
kfree(dvbdevfops); kfree(dvbdevfops);
kfree(dvbdev); kfree(dvbdev);
mutex_unlock(&dvbdev_register_lock); mutex_unlock(&dvbdev_register_lock);
@ -546,6 +553,10 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
if (IS_ERR(clsdev)) { if (IS_ERR(clsdev)) {
pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n", pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
__func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
dvb_media_device_free(dvbdev);
list_del (&dvbdev->list_head);
kfree(dvbdevfops);
kfree(dvbdev);
return PTR_ERR(clsdev); return PTR_ERR(clsdev);
} }
dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
@ -687,7 +698,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
ret = media_device_register_entity(mdev, conn); ret = media_device_register_entity(mdev, conn);
if (ret) if (ret)
return ret; return ret;
if (!ntuner) { if (!ntuner) {
ret = media_create_pad_links(mdev, ret = media_create_pad_links(mdev,
MEDIA_ENT_F_CONN_RF, MEDIA_ENT_F_CONN_RF,
@ -987,7 +998,7 @@ struct i2c_client *dvb_module_probe(const char *module_name,
unsigned char addr, unsigned char addr,
void *platform_data) void *platform_data)
{ {
struct i2c_client *client; struct i2c_client *client;
struct i2c_board_info *board_info; struct i2c_board_info *board_info;
board_info = kzalloc(sizeof(*board_info), GFP_KERNEL); board_info = kzalloc(sizeof(*board_info), GFP_KERNEL);

View File

@ -330,7 +330,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
int dvb_generic_open(struct inode *inode, struct file *file); int dvb_generic_open(struct inode *inode, struct file *file);
/** /**
* dvb_generic_close - Digital TV close function, used by DVB devices * dvb_generic_release - Digital TV close function, used by DVB devices
* *
* @inode: pointer to &struct inode. * @inode: pointer to &struct inode.
* @file: pointer to &struct file. * @file: pointer to &struct file.
@ -425,11 +425,12 @@ void dvb_module_release(struct i2c_client *client);
/* Legacy generic DVB attach function. */ /* Legacy generic DVB attach function. */
#ifdef CONFIG_MEDIA_ATTACH #ifdef CONFIG_MEDIA_ATTACH
/** /**
* dvb_attach - attaches a DVB frontend into the DVB core. * dvb_attach - attaches a DVB frontend into the DVB core.
* *
* @FUNCTION: function on a frontend module to be called. * @FUNCTION: function on a frontend module to be called.
* @ARGS...: @FUNCTION arguments. * @ARGS: @FUNCTION arguments.
* *
* This ancillary function loads a frontend module in runtime and runs * This ancillary function loads a frontend module in runtime and runs
* the @FUNCTION function there, with @ARGS. * the @FUNCTION function there, with @ARGS.